From d1ce93214340988b172f72d6be60e90bd6878a52 Mon Sep 17 00:00:00 2001 From: Eric Miller Date: Fri, 9 Feb 2018 09:59:29 -0600 Subject: [PATCH] Change default contentScale to 0.86. Add new menu item controller to tweak transition options in real-time --- CHANGELOG.md | 6 + InteractiveSideMenu.xcodeproj/project.pbxproj | 4 +- Sample/Sample.xcodeproj/project.pbxproj | 12 +- .../Controllers/HostViewController.swift | 9 +- .../SampleMenuViewController.swift | 28 +-- .../KittyViewController.storyboard | 18 +- .../KittyViewController.swift | 9 +- .../TabBarViewController.storyboard | 78 +++---- .../TabBarViewController.swift | 41 ++-- .../TweakViewController.storyboard | 190 ++++++++++++++++++ .../TweakViewController.swift | 61 ++++++ Sources/MenuContainerViewController.swift | 22 +- Sources/Options.swift | 2 +- Sources/SideMenuItemContent.swift | 3 + 14 files changed, 356 insertions(+), 127 deletions(-) create mode 100644 Sample/Sample/Menu Controllers/TweakViewController.storyboard create mode 100644 Sample/Sample/Menu Controllers/TweakViewController.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fd55c0..f62572a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes of the library will be documented in this file. ## 2.2 ### Added - Ability to globally change the drop shadow of the current content view while the menu is open (#61) +- New sample project controller to tweak the transition settings +- Status bar color can now be updated on a controller by controller basis + +### Changed +- Changed default `contentScale` value from `0.88` to `0.86` +- Updated sample project to better reflect the README demo gif ## 2.1 - [2017-10-23] ### Added diff --git a/InteractiveSideMenu.xcodeproj/project.pbxproj b/InteractiveSideMenu.xcodeproj/project.pbxproj index 1941736..14e9bb8 100644 --- a/InteractiveSideMenu.xcodeproj/project.pbxproj +++ b/InteractiveSideMenu.xcodeproj/project.pbxproj @@ -278,7 +278,7 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = is.handsome.InteractiveSideMenu; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -300,7 +300,7 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = is.handsome.InteractiveSideMenu; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/Sample/Sample.xcodeproj/project.pbxproj b/Sample/Sample.xcodeproj/project.pbxproj index 38697c1..8cc08aa 100644 --- a/Sample/Sample.xcodeproj/project.pbxproj +++ b/Sample/Sample.xcodeproj/project.pbxproj @@ -22,6 +22,8 @@ D4C58476202DD6B0006EF43A /* Storyboardable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4C58475202DD6B0006EF43A /* Storyboardable.swift */; }; D4C58478202DD6DF006EF43A /* TabBarViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D4C58477202DD6DF006EF43A /* TabBarViewController.storyboard */; }; D4C5847F202DD896006EF43A /* SampleMenuViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D4C5847E202DD896006EF43A /* SampleMenuViewController.storyboard */; }; + D4C58482202DECB4006EF43A /* TweakViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4C58481202DECB4006EF43A /* TweakViewController.swift */; }; + D4C58484202DECBB006EF43A /* TweakViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D4C58483202DECBB006EF43A /* TweakViewController.storyboard */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -79,6 +81,8 @@ D4C58475202DD6B0006EF43A /* Storyboardable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Storyboardable.swift; sourceTree = ""; }; D4C58477202DD6DF006EF43A /* TabBarViewController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = TabBarViewController.storyboard; sourceTree = ""; }; D4C5847E202DD896006EF43A /* SampleMenuViewController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = SampleMenuViewController.storyboard; sourceTree = ""; }; + D4C58481202DECB4006EF43A /* TweakViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TweakViewController.swift; sourceTree = ""; }; + D4C58483202DECBB006EF43A /* TweakViewController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = TweakViewController.storyboard; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -147,6 +151,8 @@ D4C58472202DD647006EF43A /* KittyViewController.storyboard */, 9A6755021EA8E30C00F0C71D /* TabBarViewController.swift */, D4C58477202DD6DF006EF43A /* TabBarViewController.storyboard */, + D4C58481202DECB4006EF43A /* TweakViewController.swift */, + D4C58483202DECBB006EF43A /* TweakViewController.storyboard */, ); path = "Menu Controllers"; sourceTree = ""; @@ -257,6 +263,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + D4C58484202DECBB006EF43A /* TweakViewController.storyboard in Resources */, D4C5847F202DD896006EF43A /* SampleMenuViewController.storyboard in Resources */, 881EF0B21E3102E30035DEB4 /* LaunchScreen.storyboard in Resources */, D4C58473202DD647006EF43A /* KittyViewController.storyboard in Resources */, @@ -280,6 +287,7 @@ 881EF0BF1E31037D0035DEB4 /* SampleMenuViewController.swift in Sources */, 9A6755031EA8E30C00F0C71D /* TabBarViewController.swift in Sources */, 881EF0A81E3102E30035DEB4 /* AppDelegate.swift in Sources */, + D4C58482202DECB4006EF43A /* TweakViewController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -415,7 +423,7 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = Sample/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = is.handsome.Sample; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -429,7 +437,7 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = Sample/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = is.handsome.Sample; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/Sample/Sample/Controllers/HostViewController.swift b/Sample/Sample/Controllers/HostViewController.swift index a6578df..0abe1df 100644 --- a/Sample/Sample/Controllers/HostViewController.swift +++ b/Sample/Sample/Controllers/HostViewController.swift @@ -27,10 +27,6 @@ import InteractiveSideMenu */ class HostViewController: MenuContainerViewController { - override var preferredStatusBarStyle: UIStatusBarStyle { - return .lightContent - } - override var prefersStatusBarHidden: Bool { return false } @@ -67,8 +63,9 @@ class HostViewController: MenuContainerViewController { private func contentControllers() -> [UIViewController] { let kittyController = KittyViewController.storyboardViewController() - let tabController = TabBarViewController.storyboardTabBarController() + let tabController = TabBarViewController.storyboardNavigationController() + let tweakController = TweakViewController.storyboardNavigationController() - return [kittyController, tabController] + return [kittyController, tabController, tweakController] } } diff --git a/Sample/Sample/Controllers/SampleMenuViewController.swift b/Sample/Sample/Controllers/SampleMenuViewController.swift index 035562d..d3a5211 100644 --- a/Sample/Sample/Controllers/SampleMenuViewController.swift +++ b/Sample/Sample/Controllers/SampleMenuViewController.swift @@ -27,6 +27,7 @@ class SampleMenuViewController: MenuViewController, Storyboardable { @IBOutlet fileprivate weak var tableView: UITableView! @IBOutlet fileprivate weak var avatarImageView: UIImageView! @IBOutlet fileprivate weak var avatarImageViewCenterXConstraint: NSLayoutConstraint! + private var gradientLayer = CAGradientLayer() private var gradientApplied: Bool = false @@ -50,19 +51,22 @@ class SampleMenuViewController: MenuViewController, Storyboardable { override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() - if !gradientApplied { - gradientApplied = true - avatarImageViewCenterXConstraint.constant = -(menuContainerViewController?.transitionOptions.visibleContentWidth ?? 0.0)/2 - - let gradient = CAGradientLayer() - let topColor = UIColor(red: 16.0/255.0, green: 12.0/255.0, blue: 54.0/255.0, alpha: 1.0) - let bottomColor = UIColor(red: 57.0/255.0, green: 33.0/255.0, blue: 61.0/255.0, alpha: 1.0) - gradient.startPoint = CGPoint(x: 0.0, y: 0.0) - gradient.endPoint = CGPoint(x: 1.0, y: 1.0) - gradient.colors = [topColor.cgColor, bottomColor.cgColor] - gradient.frame = view.bounds - view.layer.insertSublayer(gradient, at: 0) + avatarImageViewCenterXConstraint.constant = -(menuContainerViewController?.transitionOptions.visibleContentWidth ?? 0.0)/2 + + if gradientLayer.superlayer != nil { + gradientLayer.removeFromSuperlayer() } + let topColor = UIColor(red: 16.0/255.0, green: 12.0/255.0, blue: 54.0/255.0, alpha: 1.0) + let bottomColor = UIColor(red: 57.0/255.0, green: 33.0/255.0, blue: 61.0/255.0, alpha: 1.0) + gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0) + gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0) + gradientLayer.colors = [topColor.cgColor, bottomColor.cgColor] + gradientLayer.frame = view.bounds + view.layer.insertSublayer(gradientLayer, at: 0) + } + + deinit{ + print() } } diff --git a/Sample/Sample/Menu Controllers/KittyViewController.storyboard b/Sample/Sample/Menu Controllers/KittyViewController.storyboard index e5dbf17..0bb8b60 100644 --- a/Sample/Sample/Menu Controllers/KittyViewController.storyboard +++ b/Sample/Sample/Menu Controllers/KittyViewController.storyboard @@ -1,11 +1,13 @@ - + + + @@ -13,10 +15,6 @@ - - - - @@ -27,8 +25,8 @@ - + - - - - - - @@ -78,36 +54,12 @@ - - - - - - - - - + - - - - - - @@ -118,9 +70,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sample/Sample/Menu Controllers/TabBarViewController.swift b/Sample/Sample/Menu Controllers/TabBarViewController.swift index 50278f0..d5ff291 100644 --- a/Sample/Sample/Menu Controllers/TabBarViewController.swift +++ b/Sample/Sample/Menu Controllers/TabBarViewController.swift @@ -19,42 +19,27 @@ import UIKit import InteractiveSideMenu -/* +/** TabBarViewController is a controller relevant one of the side menu items. To indicate this it adopts `SideMenuItemContent` protocol. */ class TabBarViewController: UITabBarController, SideMenuItemContent, Storyboardable { + override var preferredStatusBarStyle: UIStatusBarStyle { + return .lightContent + } + + @IBAction func openMenu(_ sender: UIBarButtonItem) { + showSideMenu() + } + } -/* +/** The first controller of tab bar. */ -class FirstViewController: UIViewController { +class FirstViewController: UIViewController { } - /* - Show menu on click if connected tab bar controller adopts proper protocol. - */ - @IBAction func openMenu(_ sender: UIButton) { - - if let menuItemViewController = self.tabBarController as? SideMenuItemContent { - menuItemViewController.showSideMenu() - } - } -} - -/* +/** The second controller of tab bar. */ -class SecondViewController: UIViewController { - - /* - Show menu on click if connected tab bar controller adopts proper protocol. - */ - @IBAction func openMenu(_ sender: UIButton) { - - if let menuItemViewController = self.tabBarController as? SideMenuItemContent { - menuItemViewController.showSideMenu() - } - } - -} +class SecondViewController: UIViewController { } diff --git a/Sample/Sample/Menu Controllers/TweakViewController.storyboard b/Sample/Sample/Menu Controllers/TweakViewController.storyboard new file mode 100644 index 0000000..91f4837 --- /dev/null +++ b/Sample/Sample/Menu Controllers/TweakViewController.storyboard @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sample/Sample/Menu Controllers/TweakViewController.swift b/Sample/Sample/Menu Controllers/TweakViewController.swift new file mode 100644 index 0000000..4b3d11b --- /dev/null +++ b/Sample/Sample/Menu Controllers/TweakViewController.swift @@ -0,0 +1,61 @@ +// +// TweakViewController.swift +// Sample +// +// Created by Eric Miller on 2/9/18. +// Copyright © 2018 Handsome. All rights reserved. +// + +import UIKit +import InteractiveSideMenu + +class TweakViewController: UIViewController, SideMenuItemContent, Storyboardable { + + @IBOutlet private weak var animationDurationValueLabel: UILabel! + @IBOutlet private weak var contentScaleValueLabel: UILabel! + @IBOutlet private weak var visibilityValueLabel: UILabel! + @IBOutlet private weak var visibilitySlider: UISlider! + + override var preferredStatusBarStyle: UIStatusBarStyle { + return .default + } + + override func viewDidLoad() { + super.viewDidLoad() + + visibilitySlider.maximumValue = Float(UIScreen.main.bounds.width) + if let navController = parent as? UINavigationController, + let menuContainerController = navController.parent as? MenuContainerViewController { + visibilitySlider.value = Float(menuContainerController.transitionOptions.visibleContentWidth) + visibilityValueLabel.text = "\(menuContainerController.transitionOptions.visibleContentWidth)" + } + } + + @IBAction func openMenu(_ sender: UIBarButtonItem) { + showSideMenu() + } + + @IBAction func animationDurationDidChange(_ slider: UISlider) { + animationDurationValueLabel.text = "\(TimeInterval(slider.value))" + if let navController = parent as? UINavigationController, + let menuContainerController = navController.parent as? MenuContainerViewController { + menuContainerController.transitionOptions.duration = TimeInterval(slider.value) + } + } + + @IBAction func contentScaleDidChange(_ slider: UISlider) { + contentScaleValueLabel.text = "\(CGFloat(slider.value))" + if let navController = parent as? UINavigationController, + let menuContainerController = navController.parent as? MenuContainerViewController { + menuContainerController.transitionOptions.contentScale = CGFloat(slider.value) + } + } + + @IBAction func visibilityDidChange(_ slider: UISlider) { + visibilityValueLabel.text = "\(CGFloat(slider.value))" + if let navController = parent as? UINavigationController, + let menuContainerController = navController.parent as? MenuContainerViewController { + menuContainerController.transitionOptions.visibleContentWidth = CGFloat(slider.value) + } + } +} diff --git a/Sources/MenuContainerViewController.swift b/Sources/MenuContainerViewController.swift index 0316a27..3feddff 100644 --- a/Sources/MenuContainerViewController.swift +++ b/Sources/MenuContainerViewController.swift @@ -23,6 +23,10 @@ import UIKit */ open class MenuContainerViewController: UIViewController { + open override var preferredStatusBarStyle: UIStatusBarStyle { + return currentContentViewController?.preferredStatusBarStyle ?? .lightContent + } + fileprivate weak var currentContentViewController: UIViewController? fileprivate var navigationMenuTransitionDelegate: MenuTransitioningDelegate! @@ -195,18 +199,10 @@ extension UIView { view.translatesAutoresizingMaskIntoConstraints = false insertSubview(view, at: atIndex) - addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[view]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["view": view])) - addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[view]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["view": view])) - -// let top: NSLayoutConstraint -// if #available(iOS 11.0, *) { -// top = view.topAnchor.constraint(equalTo: self.safeAreaLayoutGuide.topAnchor) -// } else { -// top = view.topAnchor.constraint(equalTo: self.topAnchor) -// } -// let leading = view.leadingAnchor.constraint(equalTo: self.leadingAnchor) -// let trailing = self.trailingAnchor.constraint(equalTo: view.trailingAnchor) -// let bottom = self.bottomAnchor.constraint(equalTo: view.bottomAnchor) -// NSLayoutConstraint.activate([top, leading, trailing, bottom]) + let top = view.topAnchor.constraint(equalTo: self.topAnchor) + let leading = view.leadingAnchor.constraint(equalTo: self.leadingAnchor) + let trailing = self.trailingAnchor.constraint(equalTo: view.trailingAnchor) + let bottom = self.bottomAnchor.constraint(equalTo: view.bottomAnchor) + NSLayoutConstraint.activate([top, leading, trailing, bottom]) } } diff --git a/Sources/Options.swift b/Sources/Options.swift index 98a305e..e77836f 100644 --- a/Sources/Options.swift +++ b/Sources/Options.swift @@ -97,7 +97,7 @@ public struct TransitionOptions { /// Regular view animation options. Default value is `curveEaseInOut`. public var animationOptions: UIViewAnimationOptions = .curveEaseInOut - public init(duration: TimeInterval = 0.5, contentScale: CGFloat = 0.88, visibleContentWidth: CGFloat = 56.0) { + public init(duration: TimeInterval = 0.5, contentScale: CGFloat = 0.86, visibleContentWidth: CGFloat = 56.0) { self.duration = duration self.contentScale = contentScale self.visibleContentWidth = visibleContentWidth diff --git a/Sources/SideMenuItemContent.swift b/Sources/SideMenuItemContent.swift index 3a56d80..39bece2 100644 --- a/Sources/SideMenuItemContent.swift +++ b/Sources/SideMenuItemContent.swift @@ -37,6 +37,9 @@ extension SideMenuItemContent where Self: UIViewController { public func showSideMenu() { if let menuContainerViewController = parent as? MenuContainerViewController { menuContainerViewController.showSideMenu() + } else if let navController = parent as? UINavigationController, + let menuContainerViewController = navController.parent as? MenuContainerViewController { + menuContainerViewController.showSideMenu() } } }