From f46d760ef1aa486bca8dd2e13597aaf6a11f30a2 Mon Sep 17 00:00:00 2001 From: Saad AlBasha Date: Thu, 17 Nov 2016 14:56:35 +0200 Subject: [PATCH 1/3] - Converted to latest Swift 3 syntax. - A new option is now available to add separator between actions with customizable background color. --- Classes/CAPSOptionsMenu.swift | 248 ++++++++++-------- Classes/CAPSOptionsMenuAction.swift | 2 +- Classes/CAPSOptionsMenuButton.swift | 28 +- .../OptionsMenuDemo.xcodeproj/project.pbxproj | 6 + .../OptionsMenuDemo/AppDelegate.swift | 12 +- .../OptionsMenuDemo/MenuTableViewCell.swift | 2 +- .../MenuTableViewController.swift | 12 +- .../SmallOptionsMenuViewController.swift | 18 +- 8 files changed, 187 insertions(+), 141 deletions(-) diff --git a/Classes/CAPSOptionsMenu.swift b/Classes/CAPSOptionsMenu.swift index 8b9c675..b83504c 100644 --- a/Classes/CAPSOptionsMenu.swift +++ b/Classes/CAPSOptionsMenu.swift @@ -8,46 +8,72 @@ // DISCLAIMER: Works on iPhone 5 or newer as well as all iPads on iOS 7 or newer import UIKit +// FIXME: comparison operators with optionals were removed from the Swift Standard Libary. +// Consider refactoring the code to use the non-optional operators. +fileprivate func < (lhs: T?, rhs: T?) -> Bool { + switch (lhs, rhs) { + case let (l?, r?): + return l < r + case (nil, _?): + return true + default: + return false + } +} + +// FIXME: comparison operators with optionals were removed from the Swift Standard Libary. +// Consider refactoring the code to use the non-optional operators. +fileprivate func > (lhs: T?, rhs: T?) -> Bool { + switch (lhs, rhs) { + case let (l?, r?): + return l > r + default: + return rhs < lhs + } +} + enum AnimationOption { - case Fade - case Expand - case None + case fade + case expand + case none } class CAPSOptionsMenu: UIView, UIGestureRecognizerDelegate { - private var parentViewController: UIViewController? - private var targetNavigationController: UINavigationController? + fileprivate var parentViewController: UIViewController? + fileprivate var targetNavigationController: UINavigationController? - private var barItem: UIBarButtonItem? - private var menuScrollView: UIScrollView? + fileprivate var barItem: UIBarButtonItem? + fileprivate var menuScrollView: UIScrollView? var isShown: Bool = false - private var didTapActionButton: Bool = false + fileprivate var didTapActionButton: Bool = false - private var actions: [CAPSOptionsMenuAction] = [] - private var actionButtons: [CAPSOptionsMenuButton] = [] + fileprivate var actions: [CAPSOptionsMenuAction] = [] + fileprivate var actionButtons: [CAPSOptionsMenuButton] = [] - private var barButtonX: CGFloat = 0.0 - private var barButtonXOrientation: UIInterfaceOrientation = UIInterfaceOrientation.Unknown - private var barButtonView: UIView = UIView() + fileprivate var barButtonX: CGFloat = 0.0 + fileprivate var barButtonXOrientation: UIInterfaceOrientation = UIInterfaceOrientation.unknown + fileprivate var barButtonView: UIView = UIView() - private var closedFrame: CGRect = CGRectZero - private var openedFrame: CGRect = CGRectZero + fileprivate var closedFrame: CGRect = CGRect.zero + fileprivate var openedFrame: CGRect = CGRect.zero // Customization options defaults var menuKeepBarButtonAtEdge: Bool = true var maxMenuWidth: CGFloat = 200.0 var hasShadow: Bool = true - var menuShadowColor: UIColor = UIColor.grayColor() - var menuBackgroundColor: UIColor = UIColor.whiteColor() + var menuShadowColor: UIColor = UIColor.gray + var menuBackgroundColor: UIColor = UIColor.white var menuBorderWidth: CGFloat = 0.0 - var menuBorderColor: UIColor = UIColor.blackColor() - var menuActionButtonsTitleColor: UIColor = UIColor.blackColor() - var menuActionButtonsHiglightedColor: UIColor = UIColor.lightGrayColor() + var menuBorderColor: UIColor = UIColor.black + var menuActionButtonsTitleColor: UIColor = UIColor.black + var menuActionButtonsHiglightedColor: UIColor = UIColor.lightGray var menuCornerRadius: CGFloat = 0.0 - var menuAnimationOption: AnimationOption = AnimationOption.Expand - var menuAnimationDuration: NSTimeInterval = 0.2 + var menuAnimationOption: AnimationOption = AnimationOption.expand + var menuAnimationDuration: TimeInterval = 0.2 + var menuSeparatorBackgroundColor :UIColor = .white + var menuSeparatorEnabled : Bool = true /// Initialize with parent view controller and bar button image name /// @@ -105,24 +131,24 @@ class CAPSOptionsMenu: UIView, UIGestureRecognizerDelegate { } // MARK: - Set up - private func setUpOptionsMenu() { - self.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight] + fileprivate func setUpOptionsMenu() { + self.autoresizingMask = [UIViewAutoresizing.flexibleWidth, UIViewAutoresizing.flexibleHeight] targetNavigationController?.view.insertSubview(self, aboveSubview: targetNavigationController!.navigationBar) - self.hidden = true - self.backgroundColor = UIColor.clearColor() + self.isHidden = true + self.backgroundColor = UIColor.clear setUpMenuView() } - private func setUpMenuView() { + fileprivate func setUpMenuView() { menuScrollView = UIScrollView(frame: closedFrame) menuScrollView?.backgroundColor = menuBackgroundColor - menuScrollView?.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight] + menuScrollView?.autoresizingMask = [UIViewAutoresizing.flexibleWidth, UIViewAutoresizing.flexibleHeight] self.addSubview(menuScrollView!) - let backgroundTapGesture: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "toggleMenu") + let backgroundTapGesture: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(CAPSOptionsMenu.toggleMenu)) backgroundTapGesture.delegate = self self.addGestureRecognizer(backgroundTapGesture) @@ -135,19 +161,19 @@ class CAPSOptionsMenu: UIView, UIGestureRecognizerDelegate { if menuBorderWidth > 0.0 { addBorderToMenuView() } } - private func addShadowAndCornerRadiusToMenuView() { - self.layer.shadowColor = menuShadowColor.CGColor - self.layer.shadowOffset = CGSizeMake(0, 0) + fileprivate func addShadowAndCornerRadiusToMenuView() { + self.layer.shadowColor = menuShadowColor.cgColor + self.layer.shadowOffset = CGSize(width: 0, height: 0) self.layer.shadowRadius = 1.0 self.layer.shadowOpacity = 1.0 self.layer.masksToBounds = true self.layer.shouldRasterize = true - self.layer.rasterizationScale = UIScreen.mainScreen().scale + self.layer.rasterizationScale = UIScreen.main.scale } - private func addBorderToMenuView() { + fileprivate func addBorderToMenuView() { menuScrollView?.layer.borderWidth = menuBorderWidth - menuScrollView?.layer.borderColor = menuBorderColor.CGColor + menuScrollView?.layer.borderColor = menuBorderColor.cgColor } // MARK: - Customization @@ -168,7 +194,7 @@ class CAPSOptionsMenu: UIView, UIGestureRecognizerDelegate { /// - cornerRadius: Corner radius for the menu /// - animationOption: Animation option for the menu open/close animation style /// - animationDuration: Animation duration for the menu open/close animation - func customizeWith(maxMenuWidth maxMenuWidth: CGFloat?, shadow: Bool?, shadowColor: UIColor?, backgroundColor: UIColor?, borderWidth: CGFloat?, borderColor: UIColor?, actionButtonsTitleColor: UIColor?, actionButtonsHighlightedColor: UIColor?, cornerRadius: CGFloat?, animationOption: AnimationOption?, animationDuration: NSTimeInterval?) { + func customizeWith(maxMenuWidth: CGFloat?, shadow: Bool?, shadowColor: UIColor?, backgroundColor: UIColor?, borderWidth: CGFloat?, borderColor: UIColor?, actionButtonsTitleColor: UIColor?, actionButtonsHighlightedColor: UIColor?, cornerRadius: CGFloat?, animationOption: AnimationOption?, animationDuration: TimeInterval?) { if let mMenuWidth = maxMenuWidth { self.maxMenuWidth = mMenuWidth } if let sh = shadow { hasShadow = sh } if let shColor = shadowColor { menuShadowColor = shColor } @@ -184,7 +210,7 @@ class CAPSOptionsMenu: UIView, UIGestureRecognizerDelegate { updateForCustomizationOptions() } - private func updateForCustomizationOptions() { + fileprivate func updateForCustomizationOptions() { menuScrollView?.backgroundColor = menuBackgroundColor if menuCornerRadius > 0.0 { @@ -208,14 +234,14 @@ class CAPSOptionsMenu: UIView, UIGestureRecognizerDelegate { /// Menu Max Width /// - parameters: /// - width: Maximum width of the menu - func menuMaxWidth(width: CGFloat) { + func menuMaxWidth(_ width: CGFloat) { maxMenuWidth = width } /// Menu Has Shadow /// - parameters: /// - shadow: If `true`, shadow is added to the menu - func menuHasShadow(shadow: Bool) { + func menuHasShadow(_ shadow: Bool) { hasShadow = shadow if hasShadow { @@ -230,15 +256,15 @@ class CAPSOptionsMenu: UIView, UIGestureRecognizerDelegate { /// Menu Shadow Color /// - parameters: /// - color: Shadow color for the menu - func menuShadowColor(color: UIColor) { + func menuShadowColor(_ color: UIColor) { menuShadowColor = color - self.layer.shadowColor = menuShadowColor.CGColor + self.layer.shadowColor = menuShadowColor.cgColor } /// Menu Background Color /// - parameters: /// - color: Background color for the menu - func menuBackgroundColor(color: UIColor) { + func menuBackgroundColor(_ color: UIColor) { menuBackgroundColor = color menuScrollView?.backgroundColor = menuBackgroundColor } @@ -246,7 +272,7 @@ class CAPSOptionsMenu: UIView, UIGestureRecognizerDelegate { /// Menu Border Width /// - parameters: /// - width: Border width for the menu - func menuBorderWidth(width: CGFloat) { + func menuBorderWidth(_ width: CGFloat) { menuBorderWidth = width if menuBorderWidth > 0.0 { addBorderToMenuView() } } @@ -254,7 +280,7 @@ class CAPSOptionsMenu: UIView, UIGestureRecognizerDelegate { /// Menu Border Color /// - parameters: /// - color: Border color for the menu - func menuBorderColor(color: UIColor) { + func menuBorderColor(_ color: UIColor) { menuBorderColor = color if menuBorderWidth > 0.0 { addBorderToMenuView() } } @@ -262,21 +288,21 @@ class CAPSOptionsMenu: UIView, UIGestureRecognizerDelegate { /// Menu Action Buttons Title Color /// - parameters: /// - color: Title color for the menu action buttons - func menuActionButtonsTitleColor(color: UIColor) { + func menuActionButtonsTitleColor(_ color: UIColor) { menuActionButtonsTitleColor = color } /// Menu Action Buttons Highlighted Color /// - parameters: /// - color: Background color for the menu action buttons when tapped - func menuActionButtonsHighlightedColor(color: UIColor) { + func menuActionButtonsHighlightedColor(_ color: UIColor) { menuActionButtonsHiglightedColor = color } /// Menu Corner Radius /// - parameters: /// - radius: Corner radius for the menu - func menuCornerRadius(radius: CGFloat) { + func menuCornerRadius(_ radius: CGFloat) { menuCornerRadius = radius if menuCornerRadius > 0.0 { menuScrollView!.layer.cornerRadius = menuCornerRadius @@ -287,34 +313,34 @@ class CAPSOptionsMenu: UIView, UIGestureRecognizerDelegate { /// Menu Animation Option /// - parameters: /// - option: Animation option for the menu open/close animation style - func menuAnimationOption(option: AnimationOption) { + func menuAnimationOption(_ option: AnimationOption) { menuAnimationOption = option } /// Menu Animation Duration /// - parameters: /// - duration: Animation duration for the menu open/close animation - func menuAnimationDuration(duration: NSTimeInterval) { + func menuAnimationDuration(_ duration: TimeInterval) { menuAnimationDuration = duration } // MARK: - Bar Button Item - private func addBarButtonWithImageName(name: String) { - barItem = UIBarButtonItem(image: UIImage(named: name), style: UIBarButtonItemStyle.Plain, target: self, action: "barButtonAction:event:") + fileprivate func addBarButtonWithImageName(_ name: String) { + barItem = UIBarButtonItem(image: UIImage(named: name), style: UIBarButtonItemStyle.plain, target: self, action: #selector(CAPSOptionsMenu.barButtonAction(_:event:))) addItemToNavigationBar() } - private func addBarButtonWithImage(image: UIImage) { - barItem = UIBarButtonItem(image: image, style: UIBarButtonItemStyle.Plain, target: self, action: "barButtonAction:event:") + fileprivate func addBarButtonWithImage(_ image: UIImage) { + barItem = UIBarButtonItem(image: image, style: UIBarButtonItemStyle.plain, target: self, action: #selector(CAPSOptionsMenu.barButtonAction(_:event:))) addItemToNavigationBar() } - private func addBarButtonWithSystemItem(systemItem: UIBarButtonSystemItem) { - barItem = UIBarButtonItem(barButtonSystemItem: systemItem, target: self, action: "barButtonAction:event:") + fileprivate func addBarButtonWithSystemItem(_ systemItem: UIBarButtonSystemItem) { + barItem = UIBarButtonItem(barButtonSystemItem: systemItem, target: self, action: #selector(CAPSOptionsMenu.barButtonAction(_:event:))) addItemToNavigationBar() } - private func addItemToNavigationBar() { + fileprivate func addItemToNavigationBar() { if barItem != nil { if let navigationItem = parentViewController?.navigationItem { if navigationItem.rightBarButtonItems?.count > 1 @@ -344,73 +370,73 @@ class CAPSOptionsMenu: UIView, UIGestureRecognizerDelegate { } // MARK: - Helpers - private func getNavigationBarHeight() -> CGFloat { + fileprivate func getNavigationBarHeight() -> CGFloat { return targetNavigationController!.navigationBar.frame.origin.y + targetNavigationController!.navigationBar.frame.height } - private func getScreenBoundsForInterfaceOrientation(orientation: UIInterfaceOrientation) -> CGRect { + fileprivate func getScreenBoundsForInterfaceOrientation(_ orientation: UIInterfaceOrientation) -> CGRect { var deviceWidth: CGFloat = 0.0 var deviceHeight: CGFloat = 0.0 if (UIInterfaceOrientationIsLandscape(orientation)) { // Landscape - deviceWidth = max(UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height) - deviceHeight = min(UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height) + deviceWidth = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height) + deviceHeight = min(UIScreen.main.bounds.width, UIScreen.main.bounds.height) } else { // Portrait - deviceWidth = min(UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height) - deviceHeight = max(UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height) + deviceWidth = min(UIScreen.main.bounds.width, UIScreen.main.bounds.height) + deviceHeight = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height) } - return CGRectMake(0.0, 0.0, deviceWidth, deviceHeight) + return CGRect(x: 0.0, y: 0.0, width: deviceWidth, height: deviceHeight) } - private func setOpenClosedFrameForBarButtonFrame(statusBarOrientation: UIInterfaceOrientation) { + fileprivate func setOpenClosedFrameForBarButtonFrame(_ statusBarOrientation: UIInterfaceOrientation) { // Get appropriate screen bounds for actual interface orientation let screenBounds = getScreenBoundsForInterfaceOrientation(statusBarOrientation) // calculate y offset for bar button and make appropriate rect for bar button frame let navigationBarFrame = targetNavigationController!.navigationBar.frame let barButtonY = navigationBarFrame.origin.y + barButtonView.frame.origin.y - let frame = CGRectMake(barButtonX, barButtonY, barButtonView.frame.width, barButtonView.frame.height) + let frame = CGRect(x: barButtonX, y: barButtonY, width: barButtonView.frame.width, height: barButtonView.frame.height) // Calculate opened frames for menu - let barButtonRightOffset = screenBounds.width - CGRectGetMaxX(frame) + let barButtonRightOffset = screenBounds.width - frame.maxX let menuWidth = min(maxMenuWidth, screenBounds.width - barButtonRightOffset - barButtonY) let barMenuY = (navigationBarFrame.origin.y == 0 ? barButtonY : barButtonY - navigationBarFrame.origin.y) let menuHeight = min(CGFloat(44 * actions.count), parentViewController!.view.frame.height + navigationBarFrame.height - barMenuY - barButtonY) let barMenuX = barButtonX + barButtonView.frame.width - menuWidth - openedFrame = CGRectMake(barMenuX, barButtonY, menuWidth, menuHeight) + openedFrame = CGRect(x: barMenuX, y: barButtonY, width: menuWidth, height: menuHeight) // Calculate opened frames for menu - let barButtonCenterX = CGRectGetMidX(frame) - let barButtonCenterY = CGRectGetMidY(frame) - closedFrame = CGRectMake(barButtonCenterX, barButtonCenterY - 5.0, 0.0, 0.0) + let barButtonCenterX = frame.midX + let barButtonCenterY = frame.midY + closedFrame = CGRect(x: barButtonCenterX, y: barButtonCenterY - 5.0, width: 0.0, height: 0.0) // Update frames menuScrollView?.frame = isShown ? openedFrame : closedFrame let actionsHeight: CGFloat = CGFloat(44 * actions.count) - menuScrollView!.contentSize = CGSizeMake(menuScrollView!.frame.width, actionsHeight) + menuScrollView!.contentSize = CGSize(width: menuScrollView!.frame.width, height: actionsHeight) // Update button width for button in actionButtons { - button.frame = CGRectMake(button.frame.origin.x, button.frame.origin.y, menuWidth, button.frame.height) + button.frame = CGRect(x: button.frame.origin.x, y: button.frame.origin.y, width: menuWidth, height: button.frame.height) } } // MARK: - Menu Functions - func barButtonAction(sender:UIBarButtonItem, event: UIEvent) { - if let touches = event.allTouches() { + func barButtonAction(_ sender:UIBarButtonItem, event: UIEvent) { + if let touches = event.allTouches { if let touch = touches.first { if let view = touch.view { // Save info about bar button barButtonView = view barButtonX = view.frame.origin.x - barButtonXOrientation = UIApplication.sharedApplication().statusBarOrientation + barButtonXOrientation = UIApplication.shared.statusBarOrientation // Update menu frames - setOpenClosedFrameForBarButtonFrame(UIApplication.sharedApplication().statusBarOrientation) + setOpenClosedFrameForBarButtonFrame(UIApplication.shared.statusBarOrientation) // Open Menu toggleMenu() @@ -424,12 +450,12 @@ class CAPSOptionsMenu: UIView, UIGestureRecognizerDelegate { if !isShown { animateMenuOpen(false, completion: { () -> Void in - self.hidden = true - self.menuScrollView?.hidden = true + self.isHidden = true + self.menuScrollView?.isHidden = true }) } else { - self.hidden = false - self.menuScrollView?.hidden = false + self.isHidden = false + self.menuScrollView?.isHidden = false animateMenuOpen(true, completion: { () -> Void in self.didTapActionButton = false @@ -437,8 +463,8 @@ class CAPSOptionsMenu: UIView, UIGestureRecognizerDelegate { } } - private func animateMenuOpen(open: Bool, completion: (() -> Void)?) { - var frameAnimatingTo: CGRect = CGRectZero + fileprivate func animateMenuOpen(_ open: Bool, completion: (() -> Void)?) { + var frameAnimatingTo: CGRect = CGRect.zero if open { frameAnimatingTo = openedFrame @@ -448,20 +474,20 @@ class CAPSOptionsMenu: UIView, UIGestureRecognizerDelegate { // Animating with option switch menuAnimationOption { - case .Expand: + case .expand: menuScrollView?.alpha = 1.0 - UIView.animateWithDuration(menuAnimationDuration, animations: { () -> Void in + UIView.animate(withDuration: menuAnimationDuration, animations: { () -> Void in self.menuScrollView?.frame = frameAnimatingTo }, completion: { (completed: Bool) -> Void in if completion != nil { completion!() } }) - case .Fade: + case .fade: self.menuScrollView?.frame = self.openedFrame if isShown { menuScrollView?.alpha = 0.0 menuScrollView?.layer.shadowOpacity = 0.0 } - UIView.animateWithDuration(menuAnimationDuration, animations: { () -> Void in + UIView.animate(withDuration: menuAnimationDuration, animations: { () -> Void in if self.isShown { // Open self.menuScrollView?.alpha = 1.0 if self.hasShadow { self.menuScrollView?.layer.shadowOpacity = 1.0 } @@ -472,7 +498,7 @@ class CAPSOptionsMenu: UIView, UIGestureRecognizerDelegate { }, completion: { (completed: Bool) -> Void in if completion != nil { completion!() } }) - case .None: + case .none: self.menuScrollView?.frame = self.openedFrame if isShown { menuScrollView?.alpha = 0.0 @@ -490,36 +516,50 @@ class CAPSOptionsMenu: UIView, UIGestureRecognizerDelegate { } // MARK: - Action - func addAction(action: CAPSOptionsMenuAction) { + func addAction(_ action: CAPSOptionsMenuAction) { actions.append(action) addButtonForAction(action) // Update frame for actions let actionsHeight: CGFloat = CGFloat(44 * actions.count) openedFrame.size.height = actionsHeight - menuScrollView!.contentSize = CGSizeMake(menuScrollView!.frame.width, actionsHeight) + menuScrollView!.contentSize = CGSize(width: menuScrollView!.frame.width, height: actionsHeight) } - private func addButtonForAction(action: CAPSOptionsMenuAction) { + fileprivate func addButtonForAction(_ action: CAPSOptionsMenuAction) { let buttonYOffset: CGFloat = CGFloat(44 * (actions.count - 1)) let actionButtonFrame = CGRect(x: 0.0, y: buttonYOffset, width: 100.0, height: 44.0) let actionButton: CAPSOptionsMenuButton = CAPSOptionsMenuButton(frame: actionButtonFrame, backgroundColor: menuBackgroundColor, highlightedColor: menuActionButtonsHiglightedColor) - actionButton.titleLabel?.font = UIFont.systemFontOfSize(14.0) + actionButton.titleLabel?.font = UIFont.systemFont(ofSize: 14.0) actionButton.tag = actions.count - 1 - actionButton.setTitle(action.title, forState: UIControlState.Normal) - actionButton.contentHorizontalAlignment = UIControlContentHorizontalAlignment.Left; + actionButton.setTitle(action.title, for: UIControlState()) + actionButton.contentHorizontalAlignment = UIControlContentHorizontalAlignment.left; actionButton.contentEdgeInsets = UIEdgeInsetsMake(0, 15, 0, 0); - actionButton.setTitleColor(menuActionButtonsTitleColor, forState: UIControlState.Normal) - actionButton.addTarget(self, action: "buttonAction:", forControlEvents: UIControlEvents.TouchUpInside) + actionButton.setTitleColor(menuActionButtonsTitleColor, for: UIControlState()) + actionButton.addTarget(self, action: #selector(CAPSOptionsMenu.buttonAction(_:)), for: UIControlEvents.touchUpInside) menuScrollView!.addSubview(actionButton) actionButtons.append(actionButton) + + + if menuSeparatorEnabled { + //SB Be sure that at least actions are more than 1 + if actions.count != 0 && actions.count != 1 { + //SB loop over all actions and add sepearator + for i in 1.. Bool { + func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { if touch.view == menuScrollView { return false } @@ -540,10 +580,10 @@ class CAPSOptionsMenu: UIView, UIGestureRecognizerDelegate { super.layoutSubviews() if isShown { - let orientation = UIApplication.sharedApplication().statusBarOrientation + let orientation = UIApplication.shared.statusBarOrientation // Make sure bar button x offset is always correct depending on orientation - let idiom = UIDevice.currentDevice().userInterfaceIdiom + let idiom = UIDevice.current.userInterfaceIdiom if UIInterfaceOrientationIsPortrait(barButtonXOrientation) && UIInterfaceOrientationIsLandscape(orientation) { updateBarButtonXForIdiom(idiom, multiply: true) } else if UIInterfaceOrientationIsPortrait(orientation) && UIInterfaceOrientationIsLandscape(barButtonXOrientation) { @@ -556,14 +596,14 @@ class CAPSOptionsMenu: UIView, UIGestureRecognizerDelegate { } } - private func updateBarButtonXForIdiom(idiom: UIUserInterfaceIdiom, multiply: Bool) { + fileprivate func updateBarButtonXForIdiom(_ idiom: UIUserInterfaceIdiom, multiply: Bool) { // Static multipliers needed because barButton viw is not easily accessible var multiplier : CGFloat = 1.89 // 16:9 - if idiom == UIUserInterfaceIdiom.Pad { + if idiom == UIUserInterfaceIdiom.pad { multiplier = 1.357 // 4:3 } barButtonX = multiply ? round(barButtonX * multiplier) : round(barButtonX / multiplier) } -} \ No newline at end of file +} diff --git a/Classes/CAPSOptionsMenuAction.swift b/Classes/CAPSOptionsMenuAction.swift index ce6d5cd..63247c3 100644 --- a/Classes/CAPSOptionsMenuAction.swift +++ b/Classes/CAPSOptionsMenuAction.swift @@ -17,7 +17,7 @@ class CAPSOptionsMenuAction: NSObject { /// - parameters: /// - title: Title to be displayed on action button in menu /// - handler: Completion handler for action button tap - init(title: String, handler: ((CAPSOptionsMenuAction) -> Void)) { + init(title: String, handler: @escaping ((CAPSOptionsMenuAction) -> Void)) { actionHandler = handler super.init() diff --git a/Classes/CAPSOptionsMenuButton.swift b/Classes/CAPSOptionsMenuButton.swift index 47773ca..beb6bf1 100644 --- a/Classes/CAPSOptionsMenuButton.swift +++ b/Classes/CAPSOptionsMenuButton.swift @@ -9,8 +9,8 @@ import UIKit class CAPSOptionsMenuButton: UIButton { - var optionsMenuButtonBackgroundColor: UIColor = UIColor.whiteColor() - var optionsMenuButtonHighlightedColor: UIColor = UIColor.lightGrayColor() + var optionsMenuButtonBackgroundColor: UIColor = UIColor.white + var optionsMenuButtonHighlightedColor: UIColor = UIColor.lightGray /// Options Action Initializer /// @@ -42,31 +42,31 @@ class CAPSOptionsMenuButton: UIButton { } // MARK: - Tap handling - override func touchesBegan(touches: Set, withEvent event: UIEvent?) { - super.touchesBegan(touches, withEvent: event) + override func touchesBegan(_ touches: Set, with event: UIEvent?) { + super.touchesBegan(touches, with: event) touchDown() } - override func touchesEnded(touches: Set, withEvent event: UIEvent?) { - super.touchesEnded(touches, withEvent: event) + override func touchesEnded(_ touches: Set, with event: UIEvent?) { + super.touchesEnded(touches, with: event) touchUp() } - override func touchesCancelled(touches: Set?, withEvent event: UIEvent?) { - super.touchesCancelled(touches, withEvent: event) + override func touchesCancelled(_ touches: Set, with event: UIEvent?) { + super.touchesCancelled(touches, with: event) touchUp() } // MARK: - Touch down/up - private func touchDown() { - UIView.animateWithDuration(0.1) { () -> Void in + fileprivate func touchDown() { + UIView.animate(withDuration: 0.1, animations: { () -> Void in self.backgroundColor = self.optionsMenuButtonHighlightedColor - } + }) } - private func touchUp() { - let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(0.15 * Double(NSEC_PER_SEC))) - dispatch_after(delayTime, dispatch_get_main_queue()) { + fileprivate func touchUp() { + let delayTime = DispatchTime.now() + Double(Int64(0.15 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC) + DispatchQueue.main.asyncAfter(deadline: delayTime) { self.backgroundColor = self.optionsMenuButtonBackgroundColor } } diff --git a/OptionsMenuDemo/OptionsMenuDemo.xcodeproj/project.pbxproj b/OptionsMenuDemo/OptionsMenuDemo.xcodeproj/project.pbxproj index 47a3472..ddbac17 100644 --- a/OptionsMenuDemo/OptionsMenuDemo.xcodeproj/project.pbxproj +++ b/OptionsMenuDemo/OptionsMenuDemo.xcodeproj/project.pbxproj @@ -151,6 +151,8 @@ TargetAttributes = { A677E12B1B9793ED009074A0 = { CreatedOnToolsVersion = 7.0; + DevelopmentTeam = Z27X2MWLK6; + LastSwiftMigration = 0810; }; }; }; @@ -312,11 +314,13 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = Z27X2MWLK6; INFOPLIST_FILE = OptionsMenuDemo/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 7.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = caps.ua.edu.OptionsMenuDemo; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -324,11 +328,13 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = Z27X2MWLK6; INFOPLIST_FILE = OptionsMenuDemo/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 7.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = caps.ua.edu.OptionsMenuDemo; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Release; }; diff --git a/OptionsMenuDemo/OptionsMenuDemo/AppDelegate.swift b/OptionsMenuDemo/OptionsMenuDemo/AppDelegate.swift index a67e3c4..890d961 100644 --- a/OptionsMenuDemo/OptionsMenuDemo/AppDelegate.swift +++ b/OptionsMenuDemo/OptionsMenuDemo/AppDelegate.swift @@ -14,30 +14,30 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. return true } - func applicationWillResignActive(application: UIApplication) { + func applicationWillResignActive(_ application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. } - func applicationDidEnterBackground(application: UIApplication) { + func applicationDidEnterBackground(_ application: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } - func applicationWillEnterForeground(application: UIApplication) { + func applicationWillEnterForeground(_ application: UIApplication) { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. } - func applicationDidBecomeActive(application: UIApplication) { + func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } - func applicationWillTerminate(application: UIApplication) { + func applicationWillTerminate(_ application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } diff --git a/OptionsMenuDemo/OptionsMenuDemo/MenuTableViewCell.swift b/OptionsMenuDemo/OptionsMenuDemo/MenuTableViewCell.swift index 69437c2..9dfd0d6 100644 --- a/OptionsMenuDemo/OptionsMenuDemo/MenuTableViewCell.swift +++ b/OptionsMenuDemo/OptionsMenuDemo/MenuTableViewCell.swift @@ -17,7 +17,7 @@ class MenuTableViewCell: UITableViewCell { // Initialization code } - override func setSelected(selected: Bool, animated: Bool) { + override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) // Configure the view for the selected state diff --git a/OptionsMenuDemo/OptionsMenuDemo/MenuTableViewController.swift b/OptionsMenuDemo/OptionsMenuDemo/MenuTableViewController.swift index ca35149..e1f9cb9 100644 --- a/OptionsMenuDemo/OptionsMenuDemo/MenuTableViewController.swift +++ b/OptionsMenuDemo/OptionsMenuDemo/MenuTableViewController.swift @@ -14,7 +14,7 @@ class MenuTableViewController: UITableViewController { super.viewDidLoad() self.title = "Options Menu Demo" - self.tableView.registerNib(UINib(nibName: "MenuTableViewCell", bundle: nil), forCellReuseIdentifier: "MenuTableViewCell") + self.tableView.register(UINib(nibName: "MenuTableViewCell", bundle: nil), forCellReuseIdentifier: "MenuTableViewCell") } override func didReceiveMemoryWarning() { @@ -24,23 +24,23 @@ class MenuTableViewController: UITableViewController { // MARK: - Table view data source - override func numberOfSectionsInTableView(tableView: UITableView) -> Int { + override func numberOfSections(in tableView: UITableView) -> Int { return 1 } - override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 1 } - override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { - let cell: MenuTableViewCell = tableView.dequeueReusableCellWithIdentifier("MenuTableViewCell", forIndexPath: indexPath) as! MenuTableViewCell + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell: MenuTableViewCell = tableView.dequeueReusableCell(withIdentifier: "MenuTableViewCell", for: indexPath) as! MenuTableViewCell cell.menuTitleLabel.text = "Small Menu" return cell } - override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let smallOptionsMenuVC: SmallOptionsMenuViewController = SmallOptionsMenuViewController(nibName: "SmallOptionsMenuViewController", bundle: nil) self.navigationController?.pushViewController(smallOptionsMenuVC, animated: true) } diff --git a/OptionsMenuDemo/OptionsMenuDemo/SmallOptionsMenuViewController.swift b/OptionsMenuDemo/OptionsMenuDemo/SmallOptionsMenuViewController.swift index 8e513e1..7bd1289 100644 --- a/OptionsMenuDemo/OptionsMenuDemo/SmallOptionsMenuViewController.swift +++ b/OptionsMenuDemo/OptionsMenuDemo/SmallOptionsMenuViewController.swift @@ -29,7 +29,7 @@ class SmallOptionsMenuViewController: UIViewController { } func addOptionsMenu() { - optionsMenu = CAPSOptionsMenu(viewController: self, barButtonSystemItem: UIBarButtonSystemItem.Organize, keepBarButtonAtEdge: true) + optionsMenu = CAPSOptionsMenu(viewController: self, barButtonSystemItem: UIBarButtonSystemItem.organize, keepBarButtonAtEdge: true) optionsMenu?.menuActionButtonsHighlightedColor(UIColor(red: 242.0/255.0, green: 242.0/255.0, blue: 242.0/255.0, alpha: 1.0)) optionsMenu?.menuCornerRadius(2.0) @@ -49,20 +49,20 @@ class SmallOptionsMenuViewController: UIViewController { optionsMenu?.addAction(menuAction3) } - @IBAction func animationSegmentedControlChangedValue(sender: UISegmentedControl) { + @IBAction func animationSegmentedControlChangedValue(_ sender: UISegmentedControl) { if sender.selectedSegmentIndex == 0 { - durationSegmentedControl.hidden = false - optionsMenu?.menuAnimationOption(AnimationOption.Expand) + durationSegmentedControl.isHidden = false + optionsMenu?.menuAnimationOption(AnimationOption.expand) } else if sender.selectedSegmentIndex == 1 { - durationSegmentedControl.hidden = false - optionsMenu?.menuAnimationOption(AnimationOption.Fade) + durationSegmentedControl.isHidden = false + optionsMenu?.menuAnimationOption(AnimationOption.fade) } else { - durationSegmentedControl.hidden = true - optionsMenu?.menuAnimationOption(AnimationOption.None) + durationSegmentedControl.isHidden = true + optionsMenu?.menuAnimationOption(AnimationOption.none) } } - @IBAction func animationDurationSegmentedControlChangedValue(sender: UISegmentedControl) { + @IBAction func animationDurationSegmentedControlChangedValue(_ sender: UISegmentedControl) { if sender.selectedSegmentIndex == 0 { optionsMenu?.menuAnimationDuration(0.2) } else { From 4efab9c5148372012ad4cdf859eec5af749daefd Mon Sep 17 00:00:00 2001 From: Saad AlBasha Date: Thu, 17 Nov 2016 14:57:00 +0200 Subject: [PATCH 2/3] - signing removed. --- OptionsMenuDemo/OptionsMenuDemo.xcodeproj/project.pbxproj | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/OptionsMenuDemo/OptionsMenuDemo.xcodeproj/project.pbxproj b/OptionsMenuDemo/OptionsMenuDemo.xcodeproj/project.pbxproj index ddbac17..7c6dfca 100644 --- a/OptionsMenuDemo/OptionsMenuDemo.xcodeproj/project.pbxproj +++ b/OptionsMenuDemo/OptionsMenuDemo.xcodeproj/project.pbxproj @@ -151,7 +151,6 @@ TargetAttributes = { A677E12B1B9793ED009074A0 = { CreatedOnToolsVersion = 7.0; - DevelopmentTeam = Z27X2MWLK6; LastSwiftMigration = 0810; }; }; @@ -314,7 +313,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEVELOPMENT_TEAM = Z27X2MWLK6; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = OptionsMenuDemo/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 7.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -328,7 +327,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEVELOPMENT_TEAM = Z27X2MWLK6; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = OptionsMenuDemo/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 7.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; From 83200604ed937635ed9624430fa96fce5edf67da Mon Sep 17 00:00:00 2001 From: Saad AlBasha Date: Sun, 20 Nov 2016 09:17:44 +0200 Subject: [PATCH 3/3] - fixed separator position. --- Classes/CAPSOptionsMenu.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/CAPSOptionsMenu.swift b/Classes/CAPSOptionsMenu.swift index b83504c..279938d 100644 --- a/Classes/CAPSOptionsMenu.swift +++ b/Classes/CAPSOptionsMenu.swift @@ -546,7 +546,7 @@ class CAPSOptionsMenu: UIView, UIGestureRecognizerDelegate { if actions.count != 0 && actions.count != 1 { //SB loop over all actions and add sepearator for i in 1..