From dc8fa6796ddab4b76f4c58bf4b1951c38f62922c Mon Sep 17 00:00:00 2001 From: Eric Miller Date: Fri, 9 Feb 2018 07:12:14 -0600 Subject: [PATCH 1/2] Update to sample project to make the side menu appear more like the demo gif --- Sample/Sample.xcodeproj/project.pbxproj | 12 +- .../kitten_avatar.imageset/Contents.json | 21 ++++ .../kitten_avatar.imageset/kitten_avatar.jpeg | Bin 0 -> 5189 bytes Sample/Sample/Base.lproj/Main.storyboard | 90 +++++++++++---- .../Sample/NavigationMenuViewController.swift | 70 ------------ Sample/Sample/SampleMenuViewController.swift | 107 ++++++++++++++++++ Sample/Sample/SampleTableCell.swift | 27 +++++ 7 files changed, 234 insertions(+), 93 deletions(-) create mode 100644 Sample/Sample/Assets.xcassets/kitten_avatar.imageset/Contents.json create mode 100644 Sample/Sample/Assets.xcassets/kitten_avatar.imageset/kitten_avatar.jpeg delete mode 100644 Sample/Sample/NavigationMenuViewController.swift create mode 100644 Sample/Sample/SampleMenuViewController.swift create mode 100644 Sample/Sample/SampleTableCell.swift diff --git a/Sample/Sample.xcodeproj/project.pbxproj b/Sample/Sample.xcodeproj/project.pbxproj index 4a5ceef..b9c3527 100644 --- a/Sample/Sample.xcodeproj/project.pbxproj +++ b/Sample/Sample.xcodeproj/project.pbxproj @@ -13,10 +13,11 @@ 881EF0B21E3102E30035DEB4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 881EF0B01E3102E30035DEB4 /* LaunchScreen.storyboard */; }; 881EF0BD1E31037D0035DEB4 /* KittyViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 881EF0B91E31037D0035DEB4 /* KittyViewController.swift */; }; 881EF0BE1E31037D0035DEB4 /* HostViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 881EF0BA1E31037D0035DEB4 /* HostViewController.swift */; }; - 881EF0BF1E31037D0035DEB4 /* NavigationMenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 881EF0BB1E31037D0035DEB4 /* NavigationMenuViewController.swift */; }; + 881EF0BF1E31037D0035DEB4 /* SampleMenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 881EF0BB1E31037D0035DEB4 /* SampleMenuViewController.swift */; }; 9A15C5481EDD62BC00C4FD75 /* InteractiveSideMenu.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 881EF0C71E31049C0035DEB4 /* InteractiveSideMenu.framework */; }; 9A15C5491EDD62BC00C4FD75 /* InteractiveSideMenu.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 881EF0C71E31049C0035DEB4 /* InteractiveSideMenu.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 9A6755031EA8E30C00F0C71D /* TabBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A6755021EA8E30C00F0C71D /* TabBarViewController.swift */; }; + D4028937202CEC45009F1262 /* SampleTableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4028936202CEC45009F1262 /* SampleTableCell.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -66,9 +67,10 @@ 881EF0B31E3102E30035DEB4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 881EF0B91E31037D0035DEB4 /* KittyViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KittyViewController.swift; sourceTree = ""; }; 881EF0BA1E31037D0035DEB4 /* HostViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = HostViewController.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - 881EF0BB1E31037D0035DEB4 /* NavigationMenuViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationMenuViewController.swift; sourceTree = ""; }; + 881EF0BB1E31037D0035DEB4 /* SampleMenuViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SampleMenuViewController.swift; sourceTree = ""; }; 881EF0C21E31049C0035DEB4 /* InteractiveSideMenu.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = InteractiveSideMenu.xcodeproj; path = ../InteractiveSideMenu.xcodeproj; sourceTree = ""; }; 9A6755021EA8E30C00F0C71D /* TabBarViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabBarViewController.swift; sourceTree = ""; }; + D4028936202CEC45009F1262 /* SampleTableCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleTableCell.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -105,8 +107,9 @@ children = ( 881EF0C11E3103A80035DEB4 /* MenuContentScreens */, 881EF0BA1E31037D0035DEB4 /* HostViewController.swift */, - 881EF0BB1E31037D0035DEB4 /* NavigationMenuViewController.swift */, + 881EF0BB1E31037D0035DEB4 /* SampleMenuViewController.swift */, 881EF0A71E3102E30035DEB4 /* AppDelegate.swift */, + D4028936202CEC45009F1262 /* SampleTableCell.swift */, 881EF0AB1E3102E30035DEB4 /* Main.storyboard */, 881EF0AE1E3102E30035DEB4 /* Assets.xcassets */, 881EF0B01E3102E30035DEB4 /* LaunchScreen.storyboard */, @@ -225,7 +228,8 @@ files = ( 881EF0BD1E31037D0035DEB4 /* KittyViewController.swift in Sources */, 881EF0BE1E31037D0035DEB4 /* HostViewController.swift in Sources */, - 881EF0BF1E31037D0035DEB4 /* NavigationMenuViewController.swift in Sources */, + D4028937202CEC45009F1262 /* SampleTableCell.swift in Sources */, + 881EF0BF1E31037D0035DEB4 /* SampleMenuViewController.swift in Sources */, 9A6755031EA8E30C00F0C71D /* TabBarViewController.swift in Sources */, 881EF0A81E3102E30035DEB4 /* AppDelegate.swift in Sources */, ); diff --git a/Sample/Sample/Assets.xcassets/kitten_avatar.imageset/Contents.json b/Sample/Sample/Assets.xcassets/kitten_avatar.imageset/Contents.json new file mode 100644 index 0000000..10e14b7 --- /dev/null +++ b/Sample/Sample/Assets.xcassets/kitten_avatar.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "kitten_avatar.jpeg", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Sample/Sample/Assets.xcassets/kitten_avatar.imageset/kitten_avatar.jpeg b/Sample/Sample/Assets.xcassets/kitten_avatar.imageset/kitten_avatar.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..586426cfeeb02b1f976ed0afb526206c3c7ae1c0 GIT binary patch literal 5189 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 literal 0 HcmV?d00001 diff --git a/Sample/Sample/Base.lproj/Main.storyboard b/Sample/Sample/Base.lproj/Main.storyboard index 5ad94b9..fdd630e 100644 --- a/Sample/Sample/Base.lproj/Main.storyboard +++ b/Sample/Sample/Base.lproj/Main.storyboard @@ -1,19 +1,19 @@ - + - - + + - + - + @@ -51,10 +51,10 @@ - + - + @@ -63,17 +63,63 @@ - - - + + + + + + + + + + + + + + + + + + + + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + @@ -82,15 +128,20 @@ - + - + + - - + + + + + + @@ -224,10 +275,10 @@ - + - + @@ -247,6 +298,7 @@ + diff --git a/Sample/Sample/NavigationMenuViewController.swift b/Sample/Sample/NavigationMenuViewController.swift deleted file mode 100644 index f547bc6..0000000 --- a/Sample/Sample/NavigationMenuViewController.swift +++ /dev/null @@ -1,70 +0,0 @@ -// -// NavigationMenuViewController.swift -// -// Copyright 2017 Handsome LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -import UIKit -import InteractiveSideMenu - -/** - Menu controller is responsible for creating its content and showing/hiding menu using 'menuContainerViewController' property. - */ -class NavigationMenuViewController: MenuViewController { - - let kCellReuseIdentifier = "MenuCell" - let menuItems = ["Kitty", "TabBar cats"] - - @IBOutlet weak var tableView: UITableView! - - override var prefersStatusBarHidden: Bool { - return false - } - - override func viewDidLoad() { - super.viewDidLoad() - - // Select the initial row - tableView.selectRow(at: IndexPath(row: 0, section: 0), animated: false, scrollPosition: UITableViewScrollPosition.none) - } -} - -extension NavigationMenuViewController: UITableViewDelegate, UITableViewDataSource { - - func numberOfSections(in tableView: UITableView) -> Int { - return 1 - } - - func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return menuItems.count - } - - func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell(withIdentifier: kCellReuseIdentifier, for: indexPath) - cell.textLabel?.text = menuItems[indexPath.row] - - return cell - } - - func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - - guard let menuContainerViewController = self.menuContainerViewController else { - return - } - - menuContainerViewController.selectContentViewController(menuContainerViewController.contentViewControllers[indexPath.row]) - menuContainerViewController.hideSideMenu() - } -} diff --git a/Sample/Sample/SampleMenuViewController.swift b/Sample/Sample/SampleMenuViewController.swift new file mode 100644 index 0000000..411e387 --- /dev/null +++ b/Sample/Sample/SampleMenuViewController.swift @@ -0,0 +1,107 @@ +// +// SampleMenuViewController.swift +// +// Copyright 2017 Handsome LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit +import InteractiveSideMenu + +/** + Menu controller is responsible for creating its content and showing/hiding menu using 'menuContainerViewController' property. + */ +class SampleMenuViewController: MenuViewController { + + @IBOutlet fileprivate weak var tableView: UITableView! + @IBOutlet fileprivate weak var avatarImageView: UIImageView! + @IBOutlet fileprivate weak var avatarImageViewCenterXConstraint: NSLayoutConstraint! + + private var gradientApplied: Bool = false + + override var prefersStatusBarHidden: Bool { + return false + } + + override var preferredStatusBarStyle: UIStatusBarStyle { + return .lightContent + } + + override func viewDidLoad() { + super.viewDidLoad() + + // Select the initial row + tableView.selectRow(at: IndexPath(row: 0, section: 0), animated: false, scrollPosition: UITableViewScrollPosition.none) + + avatarImageView.layer.cornerRadius = avatarImageView.frame.size.width/2 + } + + 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) + } + } +} + +extension SampleMenuViewController: UITableViewDelegate, UITableViewDataSource { + + func numberOfSections(in tableView: UITableView) -> Int { + return 1 + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return menuContainerViewController?.contentViewControllers.count ?? 0 + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + guard let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: SampleTableCell.self), for: indexPath) as? SampleTableCell else { + preconditionFailure("Unregistered table view cell") + } + + cell.titleLabel.text = menuContainerViewController?.contentViewControllers[indexPath.row].title ?? "A Controller" + + return cell + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + guard let menuContainerViewController = self.menuContainerViewController else { + return + } + + menuContainerViewController.selectContentViewController(menuContainerViewController.contentViewControllers[indexPath.row]) + menuContainerViewController.hideSideMenu() + } + + func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { + let v = UIView() + v.backgroundColor = UIColor.clear + return v + } + + func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { + return 0.5 + } +} diff --git a/Sample/Sample/SampleTableCell.swift b/Sample/Sample/SampleTableCell.swift new file mode 100644 index 0000000..e1ec603 --- /dev/null +++ b/Sample/Sample/SampleTableCell.swift @@ -0,0 +1,27 @@ +// +// SampleTableCell.swift +// Sample +// +// Created by Eric Miller on 2/8/18. +// Copyright © 2018 Handsome. All rights reserved. +// + +import UIKit + +class SampleTableCell: UITableViewCell { + + @IBOutlet weak var titleLabel: UILabel! + @IBOutlet private weak var selectedView: UIView! + + override func awakeFromNib() { + super.awakeFromNib() + selectionStyle = .none + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + selectedView.backgroundColor = selected ? UIColor.yellow : UIColor.clear + titleLabel.textColor = selected ? UIColor.yellow : UIColor.white + } +} From 5260b0076f35680e39420ae1ca4c49382f0c3a6a Mon Sep 17 00:00:00 2001 From: Eric Miller Date: Fri, 9 Feb 2018 07:28:09 -0600 Subject: [PATCH 2/2] Refactor giant Main storyboard into individual components --- Sample/Sample.xcodeproj/project.pbxproj | 74 ++++- Sample/Sample/Base.lproj/Main.storyboard | 275 ------------------ .../Sample/{ => Cells}/SampleTableCell.swift | 0 .../HostViewController.swift | 15 +- .../SampleMenuViewController.storyboard | 115 ++++++++ .../SampleMenuViewController.swift | 2 +- Sample/Sample/Helpers/Storyboardable.swift | 50 ++++ .../KittyViewController.storyboard | 58 ++++ .../KittyViewController.swift | 2 +- .../TabBarViewController.storyboard | 146 ++++++++++ .../TabBarViewController.swift | 2 +- 11 files changed, 437 insertions(+), 302 deletions(-) rename Sample/Sample/{ => Cells}/SampleTableCell.swift (100%) rename Sample/Sample/{ => Controllers}/HostViewController.swift (80%) create mode 100644 Sample/Sample/Controllers/SampleMenuViewController.storyboard rename Sample/Sample/{ => Controllers}/SampleMenuViewController.swift (98%) create mode 100644 Sample/Sample/Helpers/Storyboardable.swift create mode 100644 Sample/Sample/Menu Controllers/KittyViewController.storyboard rename Sample/Sample/{ => Menu Controllers}/KittyViewController.swift (98%) create mode 100644 Sample/Sample/Menu Controllers/TabBarViewController.storyboard rename Sample/Sample/{ => Menu Controllers}/TabBarViewController.swift (98%) diff --git a/Sample/Sample.xcodeproj/project.pbxproj b/Sample/Sample.xcodeproj/project.pbxproj index b9c3527..38697c1 100644 --- a/Sample/Sample.xcodeproj/project.pbxproj +++ b/Sample/Sample.xcodeproj/project.pbxproj @@ -18,6 +18,10 @@ 9A15C5491EDD62BC00C4FD75 /* InteractiveSideMenu.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 881EF0C71E31049C0035DEB4 /* InteractiveSideMenu.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 9A6755031EA8E30C00F0C71D /* TabBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A6755021EA8E30C00F0C71D /* TabBarViewController.swift */; }; D4028937202CEC45009F1262 /* SampleTableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4028936202CEC45009F1262 /* SampleTableCell.swift */; }; + D4C58473202DD647006EF43A /* KittyViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D4C58472202DD647006EF43A /* KittyViewController.storyboard */; }; + 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 */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -71,6 +75,10 @@ 881EF0C21E31049C0035DEB4 /* InteractiveSideMenu.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = InteractiveSideMenu.xcodeproj; path = ../InteractiveSideMenu.xcodeproj; sourceTree = ""; }; 9A6755021EA8E30C00F0C71D /* TabBarViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabBarViewController.swift; sourceTree = ""; }; D4028936202CEC45009F1262 /* SampleTableCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleTableCell.swift; sourceTree = ""; }; + D4C58472202DD647006EF43A /* KittyViewController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = KittyViewController.storyboard; sourceTree = ""; }; + 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 = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -105,34 +113,70 @@ 881EF0A61E3102E30035DEB4 /* Sample */ = { isa = PBXGroup; children = ( - 881EF0C11E3103A80035DEB4 /* MenuContentScreens */, - 881EF0BA1E31037D0035DEB4 /* HostViewController.swift */, - 881EF0BB1E31037D0035DEB4 /* SampleMenuViewController.swift */, - 881EF0A71E3102E30035DEB4 /* AppDelegate.swift */, - D4028936202CEC45009F1262 /* SampleTableCell.swift */, 881EF0AB1E3102E30035DEB4 /* Main.storyboard */, - 881EF0AE1E3102E30035DEB4 /* Assets.xcassets */, - 881EF0B01E3102E30035DEB4 /* LaunchScreen.storyboard */, - 881EF0B31E3102E30035DEB4 /* Info.plist */, + 881EF0A71E3102E30035DEB4 /* AppDelegate.swift */, + D4C5847D202DD877006EF43A /* Controllers */, + D4C5847A202DD810006EF43A /* Menu Controllers */, + D4C5847C202DD859006EF43A /* Cells */, + D4C58474202DD6A2006EF43A /* Helpers */, + D4C5847B202DD828006EF43A /* Supporting Items */, ); path = Sample; sourceTree = ""; }; - 881EF0C11E3103A80035DEB4 /* MenuContentScreens */ = { + 881EF0C31E31049C0035DEB4 /* Products */ = { + isa = PBXGroup; + children = ( + 881EF0C71E31049C0035DEB4 /* InteractiveSideMenu.framework */, + ); + name = Products; + sourceTree = ""; + }; + D4C58474202DD6A2006EF43A /* Helpers */ = { + isa = PBXGroup; + children = ( + D4C58475202DD6B0006EF43A /* Storyboardable.swift */, + ); + path = Helpers; + sourceTree = ""; + }; + D4C5847A202DD810006EF43A /* Menu Controllers */ = { isa = PBXGroup; children = ( 881EF0B91E31037D0035DEB4 /* KittyViewController.swift */, + D4C58472202DD647006EF43A /* KittyViewController.storyboard */, 9A6755021EA8E30C00F0C71D /* TabBarViewController.swift */, + D4C58477202DD6DF006EF43A /* TabBarViewController.storyboard */, ); - name = MenuContentScreens; + path = "Menu Controllers"; sourceTree = ""; }; - 881EF0C31E31049C0035DEB4 /* Products */ = { + D4C5847B202DD828006EF43A /* Supporting Items */ = { isa = PBXGroup; children = ( - 881EF0C71E31049C0035DEB4 /* InteractiveSideMenu.framework */, + 881EF0AE1E3102E30035DEB4 /* Assets.xcassets */, + 881EF0B01E3102E30035DEB4 /* LaunchScreen.storyboard */, + 881EF0B31E3102E30035DEB4 /* Info.plist */, ); - name = Products; + name = "Supporting Items"; + sourceTree = ""; + }; + D4C5847C202DD859006EF43A /* Cells */ = { + isa = PBXGroup; + children = ( + D4028936202CEC45009F1262 /* SampleTableCell.swift */, + ); + path = Cells; + sourceTree = ""; + }; + D4C5847D202DD877006EF43A /* Controllers */ = { + isa = PBXGroup; + children = ( + 881EF0BA1E31037D0035DEB4 /* HostViewController.swift */, + 881EF0BB1E31037D0035DEB4 /* SampleMenuViewController.swift */, + D4C5847E202DD896006EF43A /* SampleMenuViewController.storyboard */, + ); + path = Controllers; sourceTree = ""; }; /* End PBXGroup section */ @@ -213,8 +257,11 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + D4C5847F202DD896006EF43A /* SampleMenuViewController.storyboard in Resources */, 881EF0B21E3102E30035DEB4 /* LaunchScreen.storyboard in Resources */, + D4C58473202DD647006EF43A /* KittyViewController.storyboard in Resources */, 881EF0AF1E3102E30035DEB4 /* Assets.xcassets in Resources */, + D4C58478202DD6DF006EF43A /* TabBarViewController.storyboard in Resources */, 881EF0AD1E3102E30035DEB4 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -228,6 +275,7 @@ files = ( 881EF0BD1E31037D0035DEB4 /* KittyViewController.swift in Sources */, 881EF0BE1E31037D0035DEB4 /* HostViewController.swift in Sources */, + D4C58476202DD6B0006EF43A /* Storyboardable.swift in Sources */, D4028937202CEC45009F1262 /* SampleTableCell.swift in Sources */, 881EF0BF1E31037D0035DEB4 /* SampleMenuViewController.swift in Sources */, 9A6755031EA8E30C00F0C71D /* TabBarViewController.swift in Sources */, diff --git a/Sample/Sample/Base.lproj/Main.storyboard b/Sample/Sample/Base.lproj/Main.storyboard index fdd630e..e8ee619 100644 --- a/Sample/Sample/Base.lproj/Main.storyboard +++ b/Sample/Sample/Base.lproj/Main.storyboard @@ -6,149 +6,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -167,140 +27,5 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Sample/Sample/SampleTableCell.swift b/Sample/Sample/Cells/SampleTableCell.swift similarity index 100% rename from Sample/Sample/SampleTableCell.swift rename to Sample/Sample/Cells/SampleTableCell.swift diff --git a/Sample/Sample/HostViewController.swift b/Sample/Sample/Controllers/HostViewController.swift similarity index 80% rename from Sample/Sample/HostViewController.swift rename to Sample/Sample/Controllers/HostViewController.swift index 779ab81..a6578df 100644 --- a/Sample/Sample/HostViewController.swift +++ b/Sample/Sample/Controllers/HostViewController.swift @@ -42,7 +42,7 @@ class HostViewController: MenuContainerViewController { self.transitionOptions = TransitionOptions(duration: 0.4, visibleContentWidth: screenSize.width / 6) // Instantiate menu view controller by identifier - self.menuViewController = self.storyboard!.instantiateViewController(withIdentifier: "NavigationMenu") as! MenuViewController + self.menuViewController = SampleMenuViewController.storyboardViewController() // Gather content items controllers self.contentViewControllers = contentControllers() @@ -66,16 +66,9 @@ class HostViewController: MenuContainerViewController { } private func contentControllers() -> [UIViewController] { - let controllersIdentifiers = ["Kitty", "TabBar"] - var contentList = [UIViewController]() + let kittyController = KittyViewController.storyboardViewController() + let tabController = TabBarViewController.storyboardTabBarController() - // Instantiate items controllers from storyboard. - for identifier in controllersIdentifiers { - if let viewController = self.storyboard?.instantiateViewController(withIdentifier: identifier) { - contentList.append(viewController) - } - } - - return contentList + return [kittyController, tabController] } } diff --git a/Sample/Sample/Controllers/SampleMenuViewController.storyboard b/Sample/Sample/Controllers/SampleMenuViewController.storyboard new file mode 100644 index 0000000..ef8d9ab --- /dev/null +++ b/Sample/Sample/Controllers/SampleMenuViewController.storyboard @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sample/Sample/SampleMenuViewController.swift b/Sample/Sample/Controllers/SampleMenuViewController.swift similarity index 98% rename from Sample/Sample/SampleMenuViewController.swift rename to Sample/Sample/Controllers/SampleMenuViewController.swift index 411e387..035562d 100644 --- a/Sample/Sample/SampleMenuViewController.swift +++ b/Sample/Sample/Controllers/SampleMenuViewController.swift @@ -22,7 +22,7 @@ import InteractiveSideMenu /** Menu controller is responsible for creating its content and showing/hiding menu using 'menuContainerViewController' property. */ -class SampleMenuViewController: MenuViewController { +class SampleMenuViewController: MenuViewController, Storyboardable { @IBOutlet fileprivate weak var tableView: UITableView! @IBOutlet fileprivate weak var avatarImageView: UIImageView! diff --git a/Sample/Sample/Helpers/Storyboardable.swift b/Sample/Sample/Helpers/Storyboardable.swift new file mode 100644 index 0000000..cdef6d2 --- /dev/null +++ b/Sample/Sample/Helpers/Storyboardable.swift @@ -0,0 +1,50 @@ +// +// Storyboardable.swift +// bthere +// +// Created by Eric Miller on 11/27/17. +// Copyright © 2017 Handsome. All rights reserved. +// + +import UIKit + +protocol Storyboardable: class { + static var defaultStoryboardName: String { get } +} + +extension Storyboardable where Self: UIViewController { + static var defaultStoryboardName: String { + return String(describing: self) + } + + static func storyboardViewController() -> Self { + let storyboard = UIStoryboard(name: defaultStoryboardName, bundle: nil) + + guard let vc = storyboard.instantiateInitialViewController() as? Self else { + fatalError("Could not instantiate initial storyboard with name: \(defaultStoryboardName)") + } + + return vc + } + + static func storyboardNavigationController() -> UINavigationController { + let storyboard = UIStoryboard(name: defaultStoryboardName, bundle: nil) + + guard let nc = storyboard.instantiateInitialViewController() as? UINavigationController else { + fatalError("Could not instantiate initial storyboard with name: \(defaultStoryboardName)") + } + + return nc + } + + static func storyboardTabBarController() -> UITabBarController { + let storyboard = UIStoryboard(name: defaultStoryboardName, bundle: nil) + + guard let tc = storyboard.instantiateInitialViewController() as? UITabBarController else { + fatalError("Could not instantiate initial storyboard with name: \(defaultStoryboardName)") + } + + return tc + } +} + diff --git a/Sample/Sample/Menu Controllers/KittyViewController.storyboard b/Sample/Sample/Menu Controllers/KittyViewController.storyboard new file mode 100644 index 0000000..e5dbf17 --- /dev/null +++ b/Sample/Sample/Menu Controllers/KittyViewController.storyboard @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sample/Sample/KittyViewController.swift b/Sample/Sample/Menu Controllers/KittyViewController.swift similarity index 98% rename from Sample/Sample/KittyViewController.swift rename to Sample/Sample/Menu Controllers/KittyViewController.swift index 605fe76..64f2fa6 100644 --- a/Sample/Sample/KittyViewController.swift +++ b/Sample/Sample/Menu Controllers/KittyViewController.swift @@ -22,7 +22,7 @@ import InteractiveSideMenu /* KittyViewController is a controller relevant one of the side menu items. To indicate this it adopts `SideMenuItemContent` protocol. */ -class KittyViewController: UIViewController, SideMenuItemContent { +class KittyViewController: UIViewController, SideMenuItemContent, Storyboardable { /* Show side menu on menu button click */ diff --git a/Sample/Sample/Menu Controllers/TabBarViewController.storyboard b/Sample/Sample/Menu Controllers/TabBarViewController.storyboard new file mode 100644 index 0000000..e39a64c --- /dev/null +++ b/Sample/Sample/Menu Controllers/TabBarViewController.storyboard @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sample/Sample/TabBarViewController.swift b/Sample/Sample/Menu Controllers/TabBarViewController.swift similarity index 98% rename from Sample/Sample/TabBarViewController.swift rename to Sample/Sample/Menu Controllers/TabBarViewController.swift index 694838f..50278f0 100644 --- a/Sample/Sample/TabBarViewController.swift +++ b/Sample/Sample/Menu Controllers/TabBarViewController.swift @@ -22,7 +22,7 @@ import InteractiveSideMenu /* TabBarViewController is a controller relevant one of the side menu items. To indicate this it adopts `SideMenuItemContent` protocol. */ -class TabBarViewController: UITabBarController, SideMenuItemContent { +class TabBarViewController: UITabBarController, SideMenuItemContent, Storyboardable { }