Commit 257c19c2 by prateeksan

Merge remote-tracking branch 'origin/development' into issue-209

parents 7fbd3d7f dd913a42
...@@ -47,6 +47,9 @@ ...@@ -47,6 +47,9 @@
location = "group:Programmatic/MenuViewController/MenuViewController.xcodeproj"> location = "group:Programmatic/MenuViewController/MenuViewController.xcodeproj">
</FileRef> </FileRef>
<FileRef <FileRef
location = "group:Programmatic/NavigationBar/NavigationBar.xcodeproj">
</FileRef>
<FileRef
location = "group:Programmatic/SearchBarView/SearchBarView.xcodeproj"> location = "group:Programmatic/SearchBarView/SearchBarView.xcodeproj">
</FileRef> </FileRef>
<FileRef <FileRef
......
...@@ -19,8 +19,7 @@ ...@@ -19,8 +19,7 @@
9663F94E1C7A74EA00AF0965 /* AppLeftViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9663F94D1C7A74EA00AF0965 /* AppLeftViewController.swift */; }; 9663F94E1C7A74EA00AF0965 /* AppLeftViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9663F94D1C7A74EA00AF0965 /* AppLeftViewController.swift */; };
9663F9501C7A74FC00AF0965 /* AppRightViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9663F94F1C7A74FC00AF0965 /* AppRightViewController.swift */; }; 9663F9501C7A74FC00AF0965 /* AppRightViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9663F94F1C7A74FC00AF0965 /* AppRightViewController.swift */; };
9663F9521C7A751D00AF0965 /* FeedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9663F9511C7A751D00AF0965 /* FeedViewController.swift */; }; 9663F9521C7A751D00AF0965 /* FeedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9663F9511C7A751D00AF0965 /* FeedViewController.swift */; };
96CC08881C7FEBD60034FF84 /* InboxViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96CC08871C7FEBD60034FF84 /* InboxViewController.swift */; }; 96CC08881C7FEBD60034FF84 /* RecipesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96CC08871C7FEBD60034FF84 /* RecipesViewController.swift */; };
96FC37D31C8CE1290040A569 /* MessagesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96FC37D21C8CE1290040A569 /* MessagesViewController.swift */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
...@@ -51,8 +50,7 @@ ...@@ -51,8 +50,7 @@
9663F94D1C7A74EA00AF0965 /* AppLeftViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppLeftViewController.swift; sourceTree = "<group>"; }; 9663F94D1C7A74EA00AF0965 /* AppLeftViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppLeftViewController.swift; sourceTree = "<group>"; };
9663F94F1C7A74FC00AF0965 /* AppRightViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppRightViewController.swift; sourceTree = "<group>"; }; 9663F94F1C7A74FC00AF0965 /* AppRightViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppRightViewController.swift; sourceTree = "<group>"; };
9663F9511C7A751D00AF0965 /* FeedViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedViewController.swift; sourceTree = "<group>"; }; 9663F9511C7A751D00AF0965 /* FeedViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedViewController.swift; sourceTree = "<group>"; };
96CC08871C7FEBD60034FF84 /* InboxViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InboxViewController.swift; sourceTree = "<group>"; }; 96CC08871C7FEBD60034FF84 /* RecipesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipesViewController.swift; sourceTree = "<group>"; };
96FC37D21C8CE1290040A569 /* MessagesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessagesViewController.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
...@@ -95,8 +93,7 @@ ...@@ -95,8 +93,7 @@
9663F94F1C7A74FC00AF0965 /* AppRightViewController.swift */, 9663F94F1C7A74FC00AF0965 /* AppRightViewController.swift */,
9663F9331C7A744600AF0965 /* SearchListViewController.swift */, 9663F9331C7A744600AF0965 /* SearchListViewController.swift */,
9663F9511C7A751D00AF0965 /* FeedViewController.swift */, 9663F9511C7A751D00AF0965 /* FeedViewController.swift */,
96CC08871C7FEBD60034FF84 /* InboxViewController.swift */, 96CC08871C7FEBD60034FF84 /* RecipesViewController.swift */,
96FC37D21C8CE1290040A569 /* MessagesViewController.swift */,
9663F9381C7A744600AF0965 /* Assets.xcassets */, 9663F9381C7A744600AF0965 /* Assets.xcassets */,
9663F93A1C7A744600AF0965 /* LaunchScreen.storyboard */, 9663F93A1C7A744600AF0965 /* LaunchScreen.storyboard */,
9663F93D1C7A744600AF0965 /* Info.plist */, 9663F93D1C7A744600AF0965 /* Info.plist */,
...@@ -175,9 +172,8 @@ ...@@ -175,9 +172,8 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
96FC37D31C8CE1290040A569 /* MessagesViewController.swift in Sources */,
9663F94A1C7A74B500AF0965 /* AppSearchBarViewController.swift in Sources */, 9663F94A1C7A74B500AF0965 /* AppSearchBarViewController.swift in Sources */,
96CC08881C7FEBD60034FF84 /* InboxViewController.swift in Sources */, 96CC08881C7FEBD60034FF84 /* RecipesViewController.swift in Sources */,
9663F9501C7A74FC00AF0965 /* AppRightViewController.swift in Sources */, 9663F9501C7A74FC00AF0965 /* AppRightViewController.swift in Sources */,
9663F9481C7A749400AF0965 /* AppNavigationController.swift in Sources */, 9663F9481C7A749400AF0965 /* AppNavigationController.swift in Sources */,
9663F9341C7A744600AF0965 /* SearchListViewController.swift in Sources */, 9663F9341C7A744600AF0965 /* SearchListViewController.swift in Sources */,
......
...@@ -39,7 +39,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate { ...@@ -39,7 +39,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch. // Override point for customization after application launch.
window = UIWindow(frame: UIScreen.mainScreen().bounds) window = UIWindow(frame: UIScreen.mainScreen().bounds)
// window!.rootViewController = SideNavigationViewController(mainViewController: AppMenuViewController(mainViewController: AppNavigationBarViewController(mainViewController: InboxViewController())), leftViewController: AppLeftViewController(), rightViewController: AppRightViewController())
window!.rootViewController = SideNavigationViewController(mainViewController: AppMenuViewController(mainViewController: AppNavigationController(rootViewController: FeedViewController())), leftViewController: AppLeftViewController(), rightViewController: AppRightViewController()) window!.rootViewController = SideNavigationViewController(mainViewController: AppMenuViewController(mainViewController: AppNavigationController(rootViewController: FeedViewController())), leftViewController: AppLeftViewController(), rightViewController: AppRightViewController())
window!.makeKeyAndVisible() window!.makeKeyAndVisible()
return true return true
......
...@@ -76,7 +76,7 @@ class AppLeftViewController: UIViewController { ...@@ -76,7 +76,7 @@ class AppLeftViewController: UIViewController {
/// Prepares the items that are displayed within the tableView. /// Prepares the items that are displayed within the tableView.
private func prepareCells() { private func prepareCells() {
items.append(Item(text: "Feed", imageName: "ic_today")) items.append(Item(text: "Feed", imageName: "ic_today"))
items.append(Item(text: "Inbox", imageName: "ic_inbox")) items.append(Item(text: "Recipes", imageName: "ic_inbox"))
} }
/// Prepares profile view. /// Prepares profile view.
......
...@@ -45,99 +45,3 @@ class AppNavigationController: NavigationController { ...@@ -45,99 +45,3 @@ class AppNavigationController: NavigationController {
navigationBar.backgroundColor = MaterialColor.blue.base navigationBar.backgroundColor = MaterialColor.blue.base
} }
} }
//class AppNavigationBarViewController: NavigationBarViewController {
// override var floatingViewController: UIViewController? {
// didSet {
// if nil == floatingViewController {
// navigationBarView.statusBarStyle = .LightContent
// }
// }
// }
//
// override func viewDidLoad() {
// super.viewDidLoad()
// prepareView()
// prepareNavigationBarView()
// }
//
// override func viewWillAppear(animated: Bool) {
// super.viewWillAppear(animated)
// navigationBarView.statusBarStyle = .LightContent
// }
//
// /// Prepares view.
// override func prepareView() {
// super.prepareView()
// view.backgroundColor = MaterialColor.black
// navigationBarViewController?.delegate = self
// }
//
// /// Toggle SideNavigationViewController left UIViewController.
// internal func handleMenuButton() {
// sideNavigationViewController?.toggleLeftView()
// }
//
// /// Toggle SideNavigationViewController right UIViewController.
// internal func handleSearchButton() {
// floatingViewController = AppSearchBarViewController(mainViewController: SearchListViewController())
// }
//
// /// Prepares the navigationBarView.
// private func prepareNavigationBarView() {
// // Title label.
// let titleLabel: UILabel = UILabel()
// titleLabel.textAlignment = .Left
// titleLabel.textColor = MaterialColor.white
//
// var image = UIImage(named: "ic_menu_white")
//
// // Menu button.
// let menuButton: FlatButton = FlatButton()
// menuButton.pulseColor = MaterialColor.white
// menuButton.pulseScale = false
// menuButton.setImage(image, forState: .Normal)
// menuButton.setImage(image, forState: .Highlighted)
// menuButton.addTarget(self, action: "handleMenuButton", forControlEvents: .TouchUpInside)
//
// // Switch control.
// let switchControl: MaterialSwitch = MaterialSwitch(state: .Off, style: .LightContent, size: .Small)
//
// // Search button.
// image = UIImage(named: "ic_search_white")
// let searchButton: FlatButton = FlatButton()
// searchButton.pulseColor = MaterialColor.white
// searchButton.pulseScale = false
// searchButton.setImage(image, forState: .Normal)
// searchButton.setImage(image, forState: .Highlighted)
// searchButton.addTarget(self, action: "handleSearchButton", forControlEvents: .TouchUpInside)
//
// navigationBarView.backgroundColor = MaterialColor.blue.base
// navigationBarView.titleLabel = titleLabel
// navigationBarView.leftControls = [menuButton]
// navigationBarView.rightControls = [switchControl, searchButton]
// }
//}
//
//
//extension AppNavigationBarViewController: NavigationBarViewControllerDelegate {
// /// Delegation method that executes when the floatingViewController will open.
// func navigationBarViewControllerWillOpenFloatingViewController(navigationBarViewController: NavigationBarViewController) {
// print("Will Open")
// }
//
// /// Delegation method that executes when the floatingViewController will close.
// func navigationBarViewControllerWillCloseFloatingViewController(navigationBarViewController: NavigationBarViewController) {
// print("Will Close")
// }
//
// /// Delegation method that executes when the floatingViewController did open.
// func navigationBarViewControllerDidOpenFloatingViewController(navigationBarViewController: NavigationBarViewController) {
// print("Did Open")
// }
//
// /// Delegation method that executes when the floatingViewController did close.
// func navigationBarViewControllerDidCloseFloatingViewController(navigationBarViewController: NavigationBarViewController) {
// print("Did Close")
// }
//}
...@@ -67,7 +67,7 @@ class AppRightViewController: UIViewController { ...@@ -67,7 +67,7 @@ class AppRightViewController: UIViewController {
/// Prepares the items that are displayed within the tableView. /// Prepares the items that are displayed within the tableView.
private func prepareCells() { private func prepareCells() {
items.append(Item(text: "Inbox", imageName: "ic_inbox")) items.append(Item(text: "Recipes", imageName: "ic_inbox"))
items.append(Item(text: "Feed", imageName: "ic_today")) items.append(Item(text: "Feed", imageName: "ic_today"))
items.append(Item(text: "Bookmarks", imageName: "ic_book")) items.append(Item(text: "Bookmarks", imageName: "ic_book"))
items.append(Item(text: "Work", imageName: "ic_work")) items.append(Item(text: "Work", imageName: "ic_work"))
......
...@@ -87,7 +87,7 @@ class AppSearchBarViewController: SearchBarViewController { ...@@ -87,7 +87,7 @@ class AppSearchBarViewController: SearchBarViewController {
clearButton.setImage(image, forState: .Highlighted) clearButton.setImage(image, forState: .Highlighted)
// Back button. // Back button.
image = UIImage(named: "ic_arrow_back_white")?.imageWithRenderingMode(.AlwaysTemplate) image = MaterialIcon.arrowDownward
let backButton: FlatButton = FlatButton() let backButton: FlatButton = FlatButton()
backButton.pulseScale = false backButton.pulseScale = false
backButton.pulseColor = MaterialColor.grey.darken4 backButton.pulseColor = MaterialColor.grey.darken4
...@@ -112,10 +112,11 @@ class AppSearchBarViewController: SearchBarViewController { ...@@ -112,10 +112,11 @@ class AppSearchBarViewController: SearchBarViewController {
searchBarView.placeholderTextColor = MaterialColor.grey.darken4 searchBarView.placeholderTextColor = MaterialColor.grey.darken4
searchBarView.textField.font = RobotoFont.regular searchBarView.textField.font = RobotoFont.regular
searchBarView.textField.delegate = self searchBarView.textField.delegate = self
searchBarView.contentInset.left = 8
searchBarView.contentInset.right = 8
searchBarView.clearButton = clearButton searchBarView.clearButton = clearButton
searchBarView.leftControls = [backButton] searchBarView.leftControls = [backButton]
searchBarView.rightControls = [moreButton]
} }
} }
......
{
"images" : [
{
"idiom" : "universal",
"filename" : "AssortmentOfDessert.jpg",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"filename" : "AssortmentOfFood.jpg",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"filename" : "AvocadoIceCream.jpg",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"filename" : "HeartCookies.jpg",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"filename" : "VeganCakeFull.jpg",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"filename" : "VeganHempBalls.jpg",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"filename" : "VeganPieAbove.jpg",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
...@@ -32,26 +32,47 @@ import UIKit ...@@ -32,26 +32,47 @@ import UIKit
import Material import Material
class FeedViewController: UIViewController { class FeedViewController: UIViewController {
/// Menu button at the top left of the navigation bar. /// NavigationBar title label.
private lazy var menuButton: FlatButton = FlatButton() private var titleLabel: UILabel!
/// Search button at the top left of the navigation bar. /// NavigationBar menu button.
private lazy var searchButton: FlatButton = FlatButton() private var menuButton: FlatButton!
/// NavigationBar switch control.
private var switchControl: MaterialSwitch!
/// NavigationBar search button.
private var searchButton: FlatButton!
/// MaterialCollectionView. /// MaterialCollectionView.
private lazy var collectionView: MaterialCollectionView = MaterialCollectionView() private var collectionView: MaterialCollectionView!
/// Image thumbnail height.
private var thumbnailHieght: CGFloat = 112
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
prepareView() prepareView()
prepareTitleLabel()
prepareMenuButton() prepareMenuButton()
prepareSwitchControl()
prepareSearchButton() prepareSearchButton()
prepareNavigationBar()
prepareCollectionView() prepareCollectionView()
} }
override func viewWillAppear(animated: Bool) { override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated) super.viewWillAppear(animated)
// Ensure that the SideNavigation is enabled.
sideNavigationViewController?.enabled = true sideNavigationViewController?.enabled = true
// Ensure that the NavigationBar is styled correctly.
if let navigationbar: NavigationBar = navigationController?.navigationBar as? NavigationBar {
navigationbar.statusBarStyle = .LightContent
navigationbar.backgroundColor = MaterialColor.blue.base
navigationbar.backButton.tintColor = MaterialColor.white
}
} }
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) { override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
...@@ -66,32 +87,32 @@ class FeedViewController: UIViewController { ...@@ -66,32 +87,32 @@ class FeedViewController: UIViewController {
/// Handler for searchButton. /// Handler for searchButton.
internal func handleSearchButton() { internal func handleSearchButton() {
presentViewController(AppSearchBarViewController(mainViewController: SearchListViewController()), animated: true, completion: nil) navigationController?.presentViewController(AppSearchBarViewController(mainViewController: SearchListViewController()), animated: true, completion: nil)
} }
/// Prepares view.
private func prepareView() { private func prepareView() {
view.backgroundColor = MaterialColor.grey.lighten4 view.backgroundColor = MaterialColor.grey.lighten4
}
let titleLabel: UILabel = UILabel() /// Prepares view.
titleLabel.text = "Material" private func prepareNavigationBar() {
titleLabel.textAlignment = .Left
titleLabel.textColor = MaterialColor.white
let detailLabel: UILabel = UILabel()
detailLabel.text = "Build Beautiful Software"
detailLabel.textAlignment = .Left
detailLabel.textColor = MaterialColor.white
navigationItem.titleLabel = titleLabel navigationItem.titleLabel = titleLabel
navigationItem.detailLabel = detailLabel
navigationItem.leftControls = [menuButton] navigationItem.leftControls = [menuButton]
navigationItem.rightControls = [searchButton] navigationItem.rightControls = [switchControl, searchButton]
}
/// Prepares the titleLabel.
private func prepareTitleLabel() {
titleLabel = UILabel()
titleLabel.text = "Recipes"
titleLabel.textAlignment = .Left
titleLabel.textColor = MaterialColor.white
} }
/// Prepares the menuButton. /// Prepares the menuButton.
private func prepareMenuButton() { private func prepareMenuButton() {
let image: UIImage? = UIImage(named: "ic_menu_white") let image: UIImage? = MaterialIcon.menu
menuButton = FlatButton()
menuButton.pulseScale = false menuButton.pulseScale = false
menuButton.pulseColor = MaterialColor.white menuButton.pulseColor = MaterialColor.white
menuButton.setImage(image, forState: .Normal) menuButton.setImage(image, forState: .Normal)
...@@ -99,10 +120,15 @@ class FeedViewController: UIViewController { ...@@ -99,10 +120,15 @@ class FeedViewController: UIViewController {
menuButton.addTarget(self, action: "handleMenuButton", forControlEvents: .TouchUpInside) menuButton.addTarget(self, action: "handleMenuButton", forControlEvents: .TouchUpInside)
} }
/// Prepares the switchControl.
private func prepareSwitchControl() {
switchControl = MaterialSwitch(state: .Off, style: .LightContent, size: .Small)
}
/// Prepares the searchButton. /// Prepares the searchButton.
private func prepareSearchButton() { private func prepareSearchButton() {
// Search button. let image: UIImage? = MaterialIcon.search
let image: UIImage? = UIImage(named: "ic_search_white") searchButton = FlatButton()
searchButton.pulseScale = false searchButton.pulseScale = false
searchButton.pulseColor = MaterialColor.white searchButton.pulseColor = MaterialColor.white
searchButton.setImage(image, forState: .Normal) searchButton.setImage(image, forState: .Normal)
...@@ -110,13 +136,16 @@ class FeedViewController: UIViewController { ...@@ -110,13 +136,16 @@ class FeedViewController: UIViewController {
searchButton.addTarget(self, action: "handleSearchButton", forControlEvents: .TouchUpInside) searchButton.addTarget(self, action: "handleSearchButton", forControlEvents: .TouchUpInside)
} }
/// Prepares the collectionView /// Prepares the collectionView.
private func prepareCollectionView() { private func prepareCollectionView() {
collectionView = MaterialCollectionView()
collectionView.dataSource = self collectionView.dataSource = self
collectionView.delegate = self collectionView.delegate = self
collectionView.spacingPreset = .Spacing1 collectionView.spacingPreset = .Spacing1
collectionView.contentInsetPreset = .Square1
collectionView.registerClass(MaterialCollectionViewCell.self, forCellWithReuseIdentifier: "MaterialCollectionViewCell") collectionView.registerClass(MaterialCollectionViewCell.self, forCellWithReuseIdentifier: "MaterialCollectionViewCell")
// Layout the collectionView.
view.addSubview(collectionView) view.addSubview(collectionView)
collectionView.translatesAutoresizingMaskIntoConstraints = false collectionView.translatesAutoresizingMaskIntoConstraints = false
MaterialLayout.alignToParent(view, child: collectionView) MaterialLayout.alignToParent(view, child: collectionView)
...@@ -131,49 +160,55 @@ extension FeedViewController: MaterialCollectionViewDataSource { ...@@ -131,49 +160,55 @@ extension FeedViewController: MaterialCollectionViewDataSource {
data: [ data: [
"title": "Summer BBQ", "title": "Summer BBQ",
"detail": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", "detail": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
"date": "February 26, 2016" "date": "February 26, 2016",
"image": "AssortmentOfDessert"
], ],
height: 158 height: thumbnailHieght
), ),
MaterialDataSourceItem( MaterialDataSourceItem(
data: [ data: [
"title": "Birthday gift", "title": "Birthday gift",
"detail": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", "detail": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
"date": "February 26, 2016" "date": "February 26, 2016",
"image": "AssortmentOfFood"
], ],
height: 158 height: thumbnailHieght
), ),
MaterialDataSourceItem( MaterialDataSourceItem(
data: [ data: [
"title": "Brunch this weekend?", "title": "Brunch this weekend?",
"detail": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", "detail": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
"date": "February 26, 2016" "date": "February 26, 2016",
"image": "AvocadoIceCream"
], ],
height: 158 height: thumbnailHieght
), ),
MaterialDataSourceItem( MaterialDataSourceItem(
data: [ data: [
"title": "Giants game", "title": "Giants game",
"detail": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", "detail": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
"date": "February 26, 2016" "date": "February 26, 2016",
"image": "HeartCookies"
], ],
height: 158 height: thumbnailHieght
), ),
MaterialDataSourceItem( MaterialDataSourceItem(
data: [ data: [
"title": "Recipe to try", "title": "Recipe to try",
"detail": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", "detail": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
"date": "February 26, 2016" "date": "February 26, 2016",
"image": "VeganHempBalls"
], ],
height: 158 height: thumbnailHieght
), ),
MaterialDataSourceItem( MaterialDataSourceItem(
data: [ data: [
"title": "Interview", "title": "Interview",
"detail": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", "detail": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
"date": "February 26, 2016" "date": "February 26, 2016",
"image": "VeganPieAbove"
], ],
height: 158 height: thumbnailHieght
) )
] ]
} }
...@@ -190,42 +225,42 @@ extension FeedViewController: MaterialCollectionViewDataSource { ...@@ -190,42 +225,42 @@ extension FeedViewController: MaterialCollectionViewDataSource {
/// Retrieves a UICollectionViewCell. /// Retrieves a UICollectionViewCell.
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let c: MaterialCollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("MaterialCollectionViewCell", forIndexPath: indexPath) as! MaterialCollectionViewCell let cell: MaterialCollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("MaterialCollectionViewCell", forIndexPath: indexPath) as! MaterialCollectionViewCell
let item: MaterialDataSourceItem = items()[indexPath.item] let item: MaterialDataSourceItem = items()[indexPath.item]
if let data: Dictionary<String, AnyObject> = item.data as? Dictionary<String, AnyObject> { if let data: Dictionary<String, AnyObject> = item.data as? Dictionary<String, AnyObject> {
var cardView: CardView? = c.contentView.subviews.first as? CardView var cardView: CardView? = cell.contentView.subviews.first as? CardView
// Only build the template if the CardView doesn't exist. // Only build the template if the CardView doesn't exist.
if nil == cardView { if nil == cardView {
cardView = CardView() cardView = CardView()
c.backgroundColor = nil cell.backgroundColor = nil
c.pulseColor = nil cell.pulseColor = nil
c.contentView.addSubview(cardView!) cell.contentView.addSubview(cardView!)
cardView!.pulseScale = false cardView!.pulseScale = false
cardView!.divider = false cardView!.divider = false
cardView!.depth = .None cardView!.depth = .None
cardView!.contentsGravityPreset = .Left
cardView!.contentInsetPreset = .Square3 cardView!.contentInsetPreset = .Square3
cardView!.contentInset.bottom /= 2 cardView!.contentInset.bottom /= 2
cardView!.cornerRadiusPreset = .None cardView!.cornerRadiusPreset = .Radius1
cardView!.rightButtonsInset.right = -8 cardView!.rightButtonsInset.right = -8
let titleLabel: UILabel = UILabel() let titleLabel: UILabel = UILabel()
titleLabel.textColor = MaterialColor.grey.darken4 titleLabel.textColor = MaterialColor.grey.darken4
titleLabel.font = RobotoFont.regularWithSize(18) titleLabel.font = RobotoFont.regularWithSize(18)
titleLabel.text = data["title"] as? String
cardView!.titleLabel = titleLabel cardView!.titleLabel = titleLabel
cardView!.titleLabelInset.left = 120
let detailLabel: UILabel = UILabel() let detailLabel: UILabel = UILabel()
detailLabel.numberOfLines = 2
detailLabel.textColor = MaterialColor.grey.darken2 detailLabel.textColor = MaterialColor.grey.darken2
detailLabel.font = RobotoFont.regular detailLabel.font = RobotoFont.regular
detailLabel.text = data["detail"] as? String
cardView!.detailView = detailLabel cardView!.detailView = detailLabel
cardView!.detailViewInset.left = 120
let image: UIImage? = UIImage(named: "ic_share_white_18pt")?.imageWithRenderingMode(.AlwaysTemplate) let image: UIImage? = UIImage(named: "ic_share_white_18pt")?.imageWithRenderingMode(.AlwaysTemplate)
...@@ -237,16 +272,27 @@ extension FeedViewController: MaterialCollectionViewDataSource { ...@@ -237,16 +272,27 @@ extension FeedViewController: MaterialCollectionViewDataSource {
shareButton.setImage(image, forState: .Highlighted) shareButton.setImage(image, forState: .Highlighted)
cardView!.rightButtons = [shareButton] cardView!.rightButtons = [shareButton]
c.contentView.addSubview(cardView!) cell.contentView.addSubview(cardView!)
} else { }
// Add the data to the cardView.
cardView?.titleLabel?.text = data["title"] as? String cardView?.titleLabel?.text = data["title"] as? String
(cardView?.detailView as? UILabel)?.text = data["detail"] as? String (cardView?.detailView as? UILabel)?.text = data["detail"] as? String
// Asynchronously the load image.
let height: CGFloat = thumbnailHieght
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
let image: UIImage? = UIImage(named: data["image"] as! String)?.resize(toHeight: height)?.crop(toWidth: height, toHeight: height)
dispatch_sync(dispatch_get_main_queue()) {
cardView?.image = image
}
} }
cardView!.frame = c.bounds // Adjust the cardView size.
cardView?.frame = cell.bounds
} }
return c return cell
} }
} }
...@@ -254,6 +300,6 @@ extension FeedViewController: MaterialCollectionViewDataSource { ...@@ -254,6 +300,6 @@ extension FeedViewController: MaterialCollectionViewDataSource {
extension FeedViewController: MaterialCollectionViewDelegate { extension FeedViewController: MaterialCollectionViewDelegate {
/// Executed when an item is selected. /// Executed when an item is selected.
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
navigationController?.pushViewController(InboxViewController(), animated: true) navigationController?.pushViewController(RecipesViewController(), animated: true)
} }
} }
\ No newline at end of file
/*
* Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. <http://cosmicmind.io>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Material nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import UIKit
import Material
private struct Item {
var text: String
var detail: String
var image: UIImage?
}
class InboxViewController: UIViewController {
/// A tableView used to display Bond entries.
private let tableView: UITableView = UITableView()
/// A list of all the Author Bond types.
private var items: Array<Item> = Array<Item>()
override func viewDidLoad() {
super.viewDidLoad()
prepareItems()
prepareView()
prepareTableView()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
sideNavigationViewController?.enabled = false
}
/**
Handles the search button click, which opens the
SideNavigationViewController.
*/
func handleSearchButton() {
sideNavigationViewController?.openRightView()
}
/// Prepares view.
private func prepareView() {
view.backgroundColor = MaterialColor.white
let titleLabel: UILabel = UILabel()
titleLabel.text = "Inbox"
titleLabel.textAlignment = .Left
titleLabel.textColor = MaterialColor.white
let detailLabel: UILabel = UILabel()
detailLabel.text = "\(items.count) Contacts"
detailLabel.textAlignment = .Left
detailLabel.textColor = MaterialColor.white
let switchControl: MaterialSwitch = MaterialSwitch(state: .Off, style: .LightContent, size: .Small)
let image: UIImage? = UIImage(named: "ic_share_white")
let shareButton: FlatButton = FlatButton()
shareButton.pulseScale = false
shareButton.pulseColor = MaterialColor.white
shareButton.setImage(image, forState: .Normal)
shareButton.setImage(image, forState: .Highlighted)
navigationItem.titleLabel = titleLabel
// navigationItem.detailLabel = detailLabel
navigationItem.rightControls = [switchControl, shareButton]
}
/// Prepares the items Array.
private func prepareItems() {
items.append(Item(text: "Summer BBQ", detail: "Wish I could come, but I am out of town this weekend.", image: UIImage(named: "Profile1")))
items.append(Item(text: "Birthday gift", detail: "Have any ideas about what we should get Heidi for her birthday?", image: UIImage(named: "Profile2")))
items.append(Item(text: "Brunch this weekend?", detail: "I'll be in your neighborhood doing errands this weekend.", image: UIImage(named: "Profile3")))
items.append(Item(text: "Giants game", detail: "Are we on this weekend for the game?", image: UIImage(named: "Profile4")))
items.append(Item(text: "Recipe to try", detail: "We should eat this: Squash, Corn and tomatillo Tacos.", image: UIImage(named: "Profile5")))
items.append(Item(text: "Interview", detail: "The candidate will be arriving at 11:30, are you free?", image: UIImage(named: "Profile6")))
items.append(Item(text: "Book recommendation", detail: "I found the book title, Surely You’re Joking, Mr. Feynman!", image: UIImage(named: "Profile7")))
items.append(Item(text: "Oui oui", detail: "Do you have Paris recommendations? Have you ever been?", image: UIImage(named: "Profile8")))
}
/// Prepares the tableView.
private func prepareTableView() {
tableView.registerClass(MaterialTableViewCell.self, forCellReuseIdentifier: "MaterialTableViewCell")
tableView.dataSource = self
tableView.delegate = self
// Use MaterialLayout to easily align the tableView.
view.addSubview(tableView)
tableView.translatesAutoresizingMaskIntoConstraints = false
MaterialLayout.alignToParent(view, child: tableView)
}
}
/// TableViewDataSource methods.
extension InboxViewController: UITableViewDataSource {
/// Determines the number of rows in the tableView.
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count;
}
/// Returns the number of sections.
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
/// Prepares the cells within the tableView.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: MaterialTableViewCell = MaterialTableViewCell(style: .Subtitle, reuseIdentifier: "MaterialTableViewCell")
let item: Item = items[indexPath.row]
cell.selectionStyle = .None
cell.textLabel!.text = item.text
cell.textLabel!.font = RobotoFont.regular
cell.detailTextLabel!.text = item.detail
cell.detailTextLabel!.font = RobotoFont.regular
cell.detailTextLabel!.textColor = MaterialColor.grey.darken1
cell.imageView!.image = item.image?.resize(toWidth: 40)
cell.imageView!.layer.cornerRadius = 20
return cell
}
/// Prepares the header within the tableView.
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = UIView(frame: CGRectMake(0, 0, view.bounds.width, 48))
header.backgroundColor = MaterialColor.white
let label: UILabel = UILabel()
label.font = RobotoFont.medium
label.textColor = MaterialColor.grey.darken1
label.text = "Today"
header.addSubview(label)
label.translatesAutoresizingMaskIntoConstraints = false
MaterialLayout.alignToParent(header, child: label, left: 24)
return header
}
}
/// UITableViewDelegate methods.
extension InboxViewController: UITableViewDelegate {
/// Sets the tableView cell height.
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 80
}
/// Sets the tableView header height.
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 48
}
/// Did select table.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
navigationController?.pushViewController(MessagesViewController(), animated: true)
}
}
...@@ -37,17 +37,29 @@ private struct Item { ...@@ -37,17 +37,29 @@ private struct Item {
var image: UIImage? var image: UIImage?
} }
class MessagesViewController: UIViewController { class RecipesViewController: UIViewController {
/// NavigationBar title label.
private var titleLabel: UILabel!
/// NavigationBar detail label.
private var detailLabel: UILabel!
/// NavigationBar share button.
private var shareButton: FlatButton!
/// A tableView used to display Bond entries. /// A tableView used to display Bond entries.
private let tableView: UITableView = UITableView() private var tableView: UITableView!
/// A list of all the Author Bond types. /// A list of all the Author Bond types.
private var items: Array<Item> = Array<Item>() private var items: Array<Item>!
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
prepareItems() prepareItems()
prepareView() prepareTitleLabel()
prepareDetailLabel()
prepareShareButton()
prepareNavigationBar()
prepareTableView() prepareTableView()
} }
...@@ -68,23 +80,12 @@ class MessagesViewController: UIViewController { ...@@ -68,23 +80,12 @@ class MessagesViewController: UIViewController {
private func prepareView() { private func prepareView() {
view.backgroundColor = MaterialColor.white view.backgroundColor = MaterialColor.white
let titleLabel: UILabel = UILabel() navigationItem.titleLabel = titleLabel
titleLabel.text = "Messages" navigationItem.detailLabel = detailLabel
titleLabel.textAlignment = .Left }
titleLabel.textColor = MaterialColor.white
let detailLabel: UILabel = UILabel()
detailLabel.text = "\(items.count) Messages"
detailLabel.textAlignment = .Left
detailLabel.textColor = MaterialColor.white
let image: UIImage? = UIImage(named: "ic_share_white")
let shareButton: FlatButton = FlatButton()
shareButton.pulseScale = false
shareButton.pulseColor = MaterialColor.white
shareButton.setImage(image, forState: .Normal)
shareButton.setImage(image, forState: .Highlighted)
/// Prepares the NavigationBar.
private func prepareNavigationBar() {
navigationItem.titleLabel = titleLabel navigationItem.titleLabel = titleLabel
navigationItem.detailLabel = detailLabel navigationItem.detailLabel = detailLabel
navigationItem.rightControls = [shareButton] navigationItem.rightControls = [shareButton]
...@@ -92,6 +93,7 @@ class MessagesViewController: UIViewController { ...@@ -92,6 +93,7 @@ class MessagesViewController: UIViewController {
/// Prepares the items Array. /// Prepares the items Array.
private func prepareItems() { private func prepareItems() {
items = Array<Item>()
items.append(Item(text: "Summer BBQ", detail: "Wish I could come, but I am out of town this weekend.", image: UIImage(named: "Profile1"))) items.append(Item(text: "Summer BBQ", detail: "Wish I could come, but I am out of town this weekend.", image: UIImage(named: "Profile1")))
items.append(Item(text: "Birthday gift", detail: "Have any ideas about what we should get Heidi for her birthday?", image: UIImage(named: "Profile2"))) items.append(Item(text: "Birthday gift", detail: "Have any ideas about what we should get Heidi for her birthday?", image: UIImage(named: "Profile2")))
items.append(Item(text: "Brunch this weekend?", detail: "I'll be in your neighborhood doing errands this weekend.", image: UIImage(named: "Profile3"))) items.append(Item(text: "Brunch this weekend?", detail: "I'll be in your neighborhood doing errands this weekend.", image: UIImage(named: "Profile3")))
...@@ -104,6 +106,7 @@ class MessagesViewController: UIViewController { ...@@ -104,6 +106,7 @@ class MessagesViewController: UIViewController {
/// Prepares the tableView. /// Prepares the tableView.
private func prepareTableView() { private func prepareTableView() {
tableView = UITableView()
tableView.registerClass(MaterialTableViewCell.self, forCellReuseIdentifier: "MaterialTableViewCell") tableView.registerClass(MaterialTableViewCell.self, forCellReuseIdentifier: "MaterialTableViewCell")
tableView.dataSource = self tableView.dataSource = self
tableView.delegate = self tableView.delegate = self
...@@ -113,10 +116,36 @@ class MessagesViewController: UIViewController { ...@@ -113,10 +116,36 @@ class MessagesViewController: UIViewController {
tableView.translatesAutoresizingMaskIntoConstraints = false tableView.translatesAutoresizingMaskIntoConstraints = false
MaterialLayout.alignToParent(view, child: tableView) MaterialLayout.alignToParent(view, child: tableView)
} }
/// Prepares the titleLabel.
private func prepareTitleLabel() {
titleLabel = UILabel()
titleLabel.text = "Messages"
titleLabel.textAlignment = .Left
titleLabel.textColor = MaterialColor.white
}
/// Prepares the detailLabel.
private func prepareDetailLabel() {
detailLabel = UILabel()
detailLabel.text = "\(items.count) Items"
detailLabel.textAlignment = .Left
detailLabel.textColor = MaterialColor.white
}
/// Prepares the shareButton.
private func prepareShareButton() {
let image: UIImage? = MaterialIcon.share
shareButton = FlatButton()
shareButton.pulseScale = false
shareButton.pulseColor = MaterialColor.white
shareButton.setImage(image, forState: .Normal)
shareButton.setImage(image, forState: .Highlighted)
}
} }
/// TableViewDataSource methods. /// TableViewDataSource methods.
extension MessagesViewController: UITableViewDataSource { extension RecipesViewController: UITableViewDataSource {
/// Determines the number of rows in the tableView. /// Determines the number of rows in the tableView.
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count; return items.count;
...@@ -163,7 +192,7 @@ extension MessagesViewController: UITableViewDataSource { ...@@ -163,7 +192,7 @@ extension MessagesViewController: UITableViewDataSource {
} }
/// UITableViewDelegate methods. /// UITableViewDelegate methods.
extension MessagesViewController: UITableViewDelegate { extension RecipesViewController: UITableViewDelegate {
/// Sets the tableView cell height. /// Sets the tableView cell height.
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 80 return 80
......
...@@ -38,6 +38,9 @@ private struct Item { ...@@ -38,6 +38,9 @@ private struct Item {
} }
class SearchListViewController: UIViewController { class SearchListViewController: UIViewController {
/// TextField for search.
private let textField: TextField = TextField()
/// A tableView used to display Bond entries. /// A tableView used to display Bond entries.
private let tableView: UITableView = UITableView() private let tableView: UITableView = UITableView()
...@@ -51,6 +54,15 @@ class SearchListViewController: UIViewController { ...@@ -51,6 +54,15 @@ class SearchListViewController: UIViewController {
prepareTableView() prepareTableView()
} }
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
textField.resignFirstResponder()
}
/** /**
Handles the search button click, which opens the Handles the search button click, which opens the
SideNavigationViewController. SideNavigationViewController.
...@@ -62,6 +74,30 @@ class SearchListViewController: UIViewController { ...@@ -62,6 +74,30 @@ class SearchListViewController: UIViewController {
/// Prepares view. /// Prepares view.
private func prepareView() { private func prepareView() {
view.backgroundColor = MaterialColor.white view.backgroundColor = MaterialColor.white
let image: UIImage? = MaterialIcon.close
let clearButton: FlatButton = FlatButton()
clearButton.pulseScale = false
clearButton.pulseColor = MaterialColor.grey.darken4
clearButton.tintColor = MaterialColor.grey.darken4
clearButton.setImage(image, forState: .Normal)
clearButton.setImage(image, forState: .Highlighted)
textField.backgroundColor = nil
textField.placeholder = "Search"
textField.placeholderTextColor = MaterialColor.grey.darken4
textField.font = RobotoFont.regularWithSize(20)
textField.tintColor = MaterialColor.grey.darken4
textField.clearButton = clearButton
navigationItem.detailView = textField
if let navigationbar: NavigationBar = navigationController?.navigationBar as? NavigationBar {
navigationbar.statusBarStyle = .Default
navigationbar.backgroundColor = MaterialColor.white
navigationbar.backButton.tintColor = MaterialColor.grey.darken4
}
} }
/// Prepares the items Array. /// Prepares the items Array.
......
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
96EFD71A1C8F73C70063F49E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96EFD7191C8F73C70063F49E /* AppDelegate.swift */; };
96EFD71C1C8F73C70063F49E /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96EFD71B1C8F73C70063F49E /* ViewController.swift */; };
96EFD7211C8F73C70063F49E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 96EFD7201C8F73C70063F49E /* Assets.xcassets */; };
96EFD7241C8F73C70063F49E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 96EFD7221C8F73C70063F49E /* LaunchScreen.storyboard */; };
96EFD72C1C8F75AA0063F49E /* Material.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96EFD72B1C8F75AA0063F49E /* Material.framework */; };
96EFD72D1C8F75AA0063F49E /* Material.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 96EFD72B1C8F75AA0063F49E /* Material.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
96EFD72E1C8F75AB0063F49E /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
96EFD72D1C8F75AA0063F49E /* Material.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
96EFD7161C8F73C60063F49E /* NavigationBar.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NavigationBar.app; sourceTree = BUILT_PRODUCTS_DIR; };
96EFD7191C8F73C70063F49E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
96EFD71B1C8F73C70063F49E /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
96EFD7201C8F73C70063F49E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
96EFD7231C8F73C70063F49E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
96EFD7251C8F73C70063F49E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
96EFD72B1C8F75AA0063F49E /* Material.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; name = Material.framework; path = "/Users/danieldahan/Library/Developer/Xcode/DerivedData/Material-hbpnflxhoouqxebjcyhbbhqyesjd/Build/Products/Debug-iphoneos/Material.framework"; sourceTree = "<absolute>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
96EFD7131C8F73C60063F49E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
96EFD72C1C8F75AA0063F49E /* Material.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
96EFD70D1C8F73C60063F49E = {
isa = PBXGroup;
children = (
96EFD72B1C8F75AA0063F49E /* Material.framework */,
96EFD7181C8F73C60063F49E /* NavigationBar */,
96EFD7171C8F73C60063F49E /* Products */,
);
sourceTree = "<group>";
};
96EFD7171C8F73C60063F49E /* Products */ = {
isa = PBXGroup;
children = (
96EFD7161C8F73C60063F49E /* NavigationBar.app */,
);
name = Products;
sourceTree = "<group>";
};
96EFD7181C8F73C60063F49E /* NavigationBar */ = {
isa = PBXGroup;
children = (
96EFD7191C8F73C70063F49E /* AppDelegate.swift */,
96EFD71B1C8F73C70063F49E /* ViewController.swift */,
96EFD7201C8F73C70063F49E /* Assets.xcassets */,
96EFD7221C8F73C70063F49E /* LaunchScreen.storyboard */,
96EFD7251C8F73C70063F49E /* Info.plist */,
);
path = NavigationBar;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
96EFD7151C8F73C60063F49E /* NavigationBar */ = {
isa = PBXNativeTarget;
buildConfigurationList = 96EFD7281C8F73C70063F49E /* Build configuration list for PBXNativeTarget "NavigationBar" */;
buildPhases = (
96EFD7121C8F73C60063F49E /* Sources */,
96EFD7131C8F73C60063F49E /* Frameworks */,
96EFD7141C8F73C60063F49E /* Resources */,
96EFD72E1C8F75AB0063F49E /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = NavigationBar;
productName = NavigationBar;
productReference = 96EFD7161C8F73C60063F49E /* NavigationBar.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
96EFD70E1C8F73C60063F49E /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0720;
LastUpgradeCheck = 0720;
ORGANIZATIONNAME = "CosmicMind, Inc.";
TargetAttributes = {
96EFD7151C8F73C60063F49E = {
CreatedOnToolsVersion = 7.2.1;
};
};
};
buildConfigurationList = 96EFD7111C8F73C60063F49E /* Build configuration list for PBXProject "NavigationBar" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 96EFD70D1C8F73C60063F49E;
productRefGroup = 96EFD7171C8F73C60063F49E /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
96EFD7151C8F73C60063F49E /* NavigationBar */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
96EFD7141C8F73C60063F49E /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
96EFD7241C8F73C70063F49E /* LaunchScreen.storyboard in Resources */,
96EFD7211C8F73C70063F49E /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
96EFD7121C8F73C60063F49E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
96EFD71C1C8F73C70063F49E /* ViewController.swift in Sources */,
96EFD71A1C8F73C70063F49E /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
96EFD7221C8F73C70063F49E /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
96EFD7231C8F73C70063F49E /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
96EFD7261C8F73C70063F49E /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
96EFD7271C8F73C70063F49E /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
96EFD7291C8F73C70063F49E /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = NavigationBar/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = io.cosmicmind.NavigationBar;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
96EFD72A1C8F73C70063F49E /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = NavigationBar/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = io.cosmicmind.NavigationBar;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
96EFD7111C8F73C60063F49E /* Build configuration list for PBXProject "NavigationBar" */ = {
isa = XCConfigurationList;
buildConfigurations = (
96EFD7261C8F73C70063F49E /* Debug */,
96EFD7271C8F73C70063F49E /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
96EFD7281C8F73C70063F49E /* Build configuration list for PBXNativeTarget "NavigationBar" */ = {
isa = XCConfigurationList;
buildConfigurations = (
96EFD7291C8F73C70063F49E /* Debug */,
96EFD72A1C8F73C70063F49E /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 96EFD70E1C8F73C60063F49E /* Project object */;
}
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:NavigationBar.xcodeproj">
</FileRef>
</Workspace>
/*
* Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. <http://cosmicmind.io>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Material nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
window = UIWindow(frame: UIScreen.mainScreen().bounds)
window!.rootViewController = ViewController()
window!.makeKeyAndVisible()
return true
}
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) {
// 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) {
// 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) {
// 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) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}
{
"images" : [
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Material-Icon-29@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Material-Icon-29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Material-Icon-40@2x-1.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Material-Icon-40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Material-Icon-60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Material-Icon-60@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Material-Icon-29.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Material-Icon-29@2x-1.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Material-Icon-40.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Material-Icon-40@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Material-Icon-76.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Material-Icon-76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Material-Icon-83.5@2x.png",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8150" systemVersion="15A204g" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8122"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
<viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<animations/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
/*
* Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. <http://cosmicmind.io>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Material nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import UIKit
import Material
class ViewController: UIViewController {
/// NavigationBar title label.
private var titleLabel: UILabel!
/// NavigationBar menu button.
private var menuButton: FlatButton!
/// NavigationBar switch control.
private var switchControl: MaterialSwitch!
/// NavigationBar search button.
private var searchButton: FlatButton!
/// Reference for NavigationBar.
private var navigationBar: NavigationBar!
override func viewDidLoad() {
super.viewDidLoad()
prepareView()
prepareTitleLabel()
prepareMenuButton()
prepareSwitchControl()
prepareSearchButton()
prepareNavigationBar()
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
navigationBar.frame = CGRectMake(0, 0, view.bounds.width, MaterialDevice.landscape ? .iPad == MaterialDevice.type ? 64 : navigationBar.intrinsicContentSize().height : 64)
}
/// General preparation statements.
private func prepareView() {
view.backgroundColor = MaterialColor.white
}
/// Prepares the titleLabel.
private func prepareTitleLabel() {
titleLabel = UILabel()
titleLabel.text = "Recipes"
titleLabel.textAlignment = .Left
titleLabel.textColor = MaterialColor.white
}
/// Prepares the menuButton.
private func prepareMenuButton() {
let image: UIImage? = MaterialIcon.menu
menuButton = FlatButton()
menuButton.pulseScale = false
menuButton.pulseColor = MaterialColor.white
menuButton.setImage(image, forState: .Normal)
menuButton.setImage(image, forState: .Highlighted)
}
/// Prepares the switchControl.
private func prepareSwitchControl() {
switchControl = MaterialSwitch(state: .Off, style: .LightContent, size: .Small)
}
/// Prepares the searchButton.
private func prepareSearchButton() {
let image: UIImage? = MaterialIcon.search
searchButton = FlatButton()
searchButton.pulseScale = false
searchButton.pulseColor = MaterialColor.white
searchButton.setImage(image, forState: .Normal)
searchButton.setImage(image, forState: .Highlighted)
}
/// Prepare navigationBar.
private func prepareNavigationBar() {
navigationBar = NavigationBar()
navigationBar.statusBarStyle = .LightContent
navigationBar.tintColor = MaterialColor.white
navigationBar.backgroundColor = MaterialColor.blue.base
view.addSubview(navigationBar)
let item: UINavigationItem = UINavigationItem()
item.titleLabel = titleLabel
item.leftControls = [menuButton]
item.rightControls = [switchControl, searchButton]
navigationBar.pushNavigationItem(item, animated: true)
}
}
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
96A71F451C74ABCB00C0C4AE /* MaterialBorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96A71F441C74ABCB00C0C4AE /* MaterialBorder.swift */; }; 96A71F451C74ABCB00C0C4AE /* MaterialBorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96A71F441C74ABCB00C0C4AE /* MaterialBorder.swift */; };
96A71FB31C764E3200C0C4AE /* StatusBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96A71FB21C764E3200C0C4AE /* StatusBarView.swift */; }; 96A71FB31C764E3200C0C4AE /* StatusBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96A71FB21C764E3200C0C4AE /* StatusBarView.swift */; };
96A71FB61C7651AA00C0C4AE /* ControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96A71FB01C7649F800C0C4AE /* ControlView.swift */; }; 96A71FB61C7651AA00C0C4AE /* ControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96A71FB01C7649F800C0C4AE /* ControlView.swift */; };
96BE340F1C8E68EF007D02BE /* MaterialIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BE340E1C8E68EF007D02BE /* MaterialIcon.swift */; };
96CC08311C7CCB7C0034FF84 /* MaterialBorder.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96A71F441C74ABCB00C0C4AE /* MaterialBorder.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 96CC08311C7CCB7C0034FF84 /* MaterialBorder.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96A71F441C74ABCB00C0C4AE /* MaterialBorder.swift */; settings = {ATTRIBUTES = (Public, ); }; };
96CC08321C7CCB7C0034FF84 /* MenuViewController.swift in Headers */ = {isa = PBXBuildFile; fileRef = 9626C2DD1C795017007CA8E0 /* MenuViewController.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 96CC08321C7CCB7C0034FF84 /* MenuViewController.swift in Headers */ = {isa = PBXBuildFile; fileRef = 9626C2DD1C795017007CA8E0 /* MenuViewController.swift */; settings = {ATTRIBUTES = (Public, ); }; };
96CC08331C7CCB7C0034FF84 /* MaterialSwitch.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96A71EC61C6FFF0500C0C4AE /* MaterialSwitch.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 96CC08331C7CCB7C0034FF84 /* MaterialSwitch.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96A71EC61C6FFF0500C0C4AE /* MaterialSwitch.swift */; settings = {ATTRIBUTES = (Public, ); }; };
...@@ -185,6 +186,7 @@ ...@@ -185,6 +186,7 @@
96A71F441C74ABCB00C0C4AE /* MaterialBorder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaterialBorder.swift; sourceTree = "<group>"; }; 96A71F441C74ABCB00C0C4AE /* MaterialBorder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaterialBorder.swift; sourceTree = "<group>"; };
96A71FB01C7649F800C0C4AE /* ControlView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ControlView.swift; sourceTree = "<group>"; }; 96A71FB01C7649F800C0C4AE /* ControlView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ControlView.swift; sourceTree = "<group>"; };
96A71FB21C764E3200C0C4AE /* StatusBarView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusBarView.swift; sourceTree = "<group>"; }; 96A71FB21C764E3200C0C4AE /* StatusBarView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusBarView.swift; sourceTree = "<group>"; };
96BE340E1C8E68EF007D02BE /* MaterialIcon.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaterialIcon.swift; sourceTree = "<group>"; };
96CC083C1C7CF9D40034FF84 /* StatusBarViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusBarViewController.swift; sourceTree = "<group>"; }; 96CC083C1C7CF9D40034FF84 /* StatusBarViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusBarViewController.swift; sourceTree = "<group>"; };
96CC088B1C7FEC170034FF84 /* MaterialCollectionView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaterialCollectionView.swift; sourceTree = "<group>"; }; 96CC088B1C7FEC170034FF84 /* MaterialCollectionView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaterialCollectionView.swift; sourceTree = "<group>"; };
96CC088C1C7FEC170034FF84 /* MaterialCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaterialCollectionViewCell.swift; sourceTree = "<group>"; }; 96CC088C1C7FEC170034FF84 /* MaterialCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaterialCollectionViewCell.swift; sourceTree = "<group>"; };
...@@ -349,6 +351,14 @@ ...@@ -349,6 +351,14 @@
name = Switch; name = Switch;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
96BE340D1C8E68BB007D02BE /* Icon */ = {
isa = PBXGroup;
children = (
96BE340E1C8E68EF007D02BE /* MaterialIcon.swift */,
);
name = Icon;
sourceTree = "<group>";
};
96CC08561C7E0EC00034FF84 /* ControlView */ = { 96CC08561C7E0EC00034FF84 /* ControlView */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
...@@ -376,6 +386,8 @@ ...@@ -376,6 +386,8 @@
96D88BFD1C1328D800B91418 /* LICENSE */, 96D88BFD1C1328D800B91418 /* LICENSE */,
96D88BFC1C1328D800B91418 /* Info.plist */, 96D88BFC1C1328D800B91418 /* Info.plist */,
96D88C091C1328D800B91418 /* Material.h */, 96D88C091C1328D800B91418 /* Material.h */,
96334EF51C8B84660083986B /* Assets.xcassets */,
96BE340D1C8E68BB007D02BE /* Icon */,
96D88C501C132A2C00B91418 /* Extensions */, 96D88C501C132A2C00B91418 /* Extensions */,
96D88C531C132A6900B91418 /* View */, 96D88C531C132A6900B91418 /* View */,
96D88C521C132A5700B91418 /* Layout */, 96D88C521C132A5700B91418 /* Layout */,
...@@ -399,7 +411,6 @@ ...@@ -399,7 +411,6 @@
9626C2DB1C794FBB007CA8E0 /* SearchBar */, 9626C2DB1C794FBB007CA8E0 /* SearchBar */,
9626C2DA1C794FA5007CA8E0 /* NavigationBar */, 9626C2DA1C794FA5007CA8E0 /* NavigationBar */,
9626C2DC1C794FE5007CA8E0 /* SideNavigation */, 9626C2DC1C794FE5007CA8E0 /* SideNavigation */,
96334EF51C8B84660083986B /* Assets.xcassets */,
); );
path = Sources; path = Sources;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -754,6 +765,7 @@ ...@@ -754,6 +765,7 @@
96CC08921C7FEC170034FF84 /* MaterialCollectionView.swift in Sources */, 96CC08921C7FEC170034FF84 /* MaterialCollectionView.swift in Sources */,
96A71EC71C6FFF0500C0C4AE /* MaterialSwitch.swift in Sources */, 96A71EC71C6FFF0500C0C4AE /* MaterialSwitch.swift in Sources */,
96CC08951C7FEC170034FF84 /* MaterialCollectionViewDelegate.swift in Sources */, 96CC08951C7FEC170034FF84 /* MaterialCollectionViewDelegate.swift in Sources */,
96BE340F1C8E68EF007D02BE /* MaterialIcon.swift in Sources */,
96CC08971C7FEC170034FF84 /* MaterialDataSourceItem.swift in Sources */, 96CC08971C7FEC170034FF84 /* MaterialDataSourceItem.swift in Sources */,
96D88C221C1328D800B91418 /* FabButton.swift in Sources */, 96D88C221C1328D800B91418 /* FabButton.swift in Sources */,
96D88C3F1C1328D800B91418 /* RaisedButton.swift in Sources */, 96D88C3F1C1328D800B91418 /* RaisedButton.swift in Sources */,
......
{
"images" : [
{
"idiom" : "universal",
"filename" : "ic_add_white.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "ic_add_white_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "ic_add_white_3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"filename" : "ic_arrow_downward_white.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "ic_arrow_downward_white_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "ic_arrow_downward_white_3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"filename" : "ic_close_white.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "ic_close_white_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "ic_close_white_3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"filename" : "ic_menu_white.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "ic_menu_white_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "ic_menu_white_3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"filename" : "ic_search_white.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "ic_search_white_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "ic_search_white_3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"filename" : "ic_share_white.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "ic_share_white_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "ic_share_white_3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
...@@ -110,17 +110,19 @@ public class ImageCardView : MaterialPulseView { ...@@ -110,17 +110,19 @@ public class ImageCardView : MaterialPulseView {
*/ */
public var maxImageHeight: CGFloat = 0 { public var maxImageHeight: CGFloat = 0 {
didSet { didSet {
if let v: UIImage = image {
if 0 < maxImageHeight { if 0 < maxImageHeight {
prepareImageLayer() prepareImageLayer()
let h: CGFloat = image!.size.height / contentsScale let h: CGFloat = v.size.height / contentsScale
imageLayer?.frame.size.height = maxImageHeight < h ? maxImageHeight : h imageLayer?.frame.size.height = maxImageHeight < h ? maxImageHeight : h
} else { } else {
maxImageHeight = 0 maxImageHeight = 0
imageLayer?.frame.size.height = nil == image ? 0 : image!.size.height / contentsScale imageLayer?.frame.size.height = nil == image ? 0 : v.size.height / contentsScale
} }
reloadView() reloadView()
} }
} }
}
/** /**
:name: contentsRect :name: contentsRect
......
...@@ -530,7 +530,7 @@ public class MaterialButton : UIButton { ...@@ -530,7 +530,7 @@ public class MaterialButton : UIButton {
} }
pulseLayer.addAnimation(MaterialAnimation.scale(3 * d, duration: t), forKey: nil) pulseLayer.addAnimation(MaterialAnimation.scale(3 * d, duration: t), forKey: nil)
MaterialAnimation.delay(t) { [weak self] in MaterialAnimation.delay(t) { [weak self] in
if nil != self && nil != self!.pulseColor && 0 < self!.pulseColorOpacity { if nil != self?.pulseColor && 0 < self?.pulseColorOpacity {
MaterialAnimation.animateWithDuration(t, animations: { MaterialAnimation.animateWithDuration(t, animations: {
pulseLayer.hidden = true pulseLayer.hidden = true
}) { }) {
......
...@@ -636,7 +636,7 @@ public class MaterialCollectionViewCell : UICollectionViewCell { ...@@ -636,7 +636,7 @@ public class MaterialCollectionViewCell : UICollectionViewCell {
} }
pulseLayer.addAnimation(MaterialAnimation.scale(3 * d, duration: t), forKey: nil) pulseLayer.addAnimation(MaterialAnimation.scale(3 * d, duration: t), forKey: nil)
MaterialAnimation.delay(t) { [weak self] in MaterialAnimation.delay(t) { [weak self] in
if nil != self && nil != self!.pulseColor && 0 < self!.pulseColorOpacity { if nil != self?.pulseColor && 0 < self?.pulseColorOpacity {
MaterialAnimation.animateWithDuration(t, animations: { MaterialAnimation.animateWithDuration(t, animations: {
pulseLayer.hidden = true pulseLayer.hidden = true
}) { }) {
......
...@@ -38,6 +38,45 @@ public enum MaterialDeviceType { ...@@ -38,6 +38,45 @@ public enum MaterialDeviceType {
} }
public struct MaterialDevice { public struct MaterialDevice {
/// Gets the model name for the device.
public static var model: String {
var systemInfo: utsname = utsname()
uname(&systemInfo)
let machineMirror: Mirror = Mirror(reflecting: systemInfo.machine)
let identifier: String = machineMirror.children.reduce("") { (identifier, element) in
guard let value = element.value as? Int8 where value != 0 else { return identifier }
return identifier + String(UnicodeScalar(UInt8(value)))
}
switch identifier {
case "iPod5,1": return "iPod Touch 5"
case "iPod7,1": return "iPod Touch 6"
case "iPhone3,1", "iPhone3,2", "iPhone3,3": return "iPhone 4"
case "iPhone4,1": return "iPhone 4s"
case "iPhone5,1", "iPhone5,2": return "iPhone 5"
case "iPhone5,3", "iPhone5,4": return "iPhone 5c"
case "iPhone6,1", "iPhone6,2": return "iPhone 5s"
case "iPhone7,2": return "iPhone 6"
case "iPhone7,1": return "iPhone 6 Plus"
case "iPhone8,1": return "iPhone 6s"
case "iPhone8,2": return "iPhone 6s Plus"
case "iPad2,1", "iPad2,2", "iPad2,3", "iPad2,4": return "iPad 2"
case "iPad3,1", "iPad3,2", "iPad3,3": return "iPad 3"
case "iPad3,4", "iPad3,5", "iPad3,6": return "iPad 4"
case "iPad4,1", "iPad4,2", "iPad4,3": return "iPad Air"
case "iPad5,3", "iPad5,4": return "iPad Air 2"
case "iPad2,5", "iPad2,6", "iPad2,7": return "iPad Mini"
case "iPad4,4", "iPad4,5", "iPad4,6": return "iPad Mini 2"
case "iPad4,7", "iPad4,8", "iPad4,9": return "iPad Mini 3"
case "iPad5,1", "iPad5,2": return "iPad Mini 4"
case "iPad6,7", "iPad6,8": return "iPad Pro"
case "AppleTV5,3": return "Apple TV"
case "i386", "x86_64": return "Simulator"
default: return identifier
}
}
/// Retrieves the current device type. /// Retrieves the current device type.
public static var type: MaterialDeviceType { public static var type: MaterialDeviceType {
switch UIDevice.currentDevice().userInterfaceIdiom { switch UIDevice.currentDevice().userInterfaceIdiom {
...@@ -47,7 +86,7 @@ public struct MaterialDevice { ...@@ -47,7 +86,7 @@ public struct MaterialDevice {
return .iPhone return .iPhone
case .TV: case .TV:
return .TV return .TV
case .Unspecified: default:
return .Unspecified return .Unspecified
} }
} }
......
/*
* Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. <http://cosmicmind.io>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Material nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import UIKit
public struct MaterialIcon {
public static let add: UIImage? = UIImage(named: "ic_add_white", inBundle: NSBundle(identifier: "io.cosmicmind.Material"), compatibleWithTraitCollection: nil)?.imageWithRenderingMode(.AlwaysTemplate)
public static let arrowBack: UIImage? = UIImage(named: "ic_arrow_back_white", inBundle: NSBundle(identifier: "io.cosmicmind.Material"), compatibleWithTraitCollection: nil)?.imageWithRenderingMode(.AlwaysTemplate)
public static let arrowDownward: UIImage? = UIImage(named: "ic_arrow_downward_white", inBundle: NSBundle(identifier: "io.cosmicmind.Material"), compatibleWithTraitCollection: nil)?.imageWithRenderingMode(.AlwaysTemplate)
public static let clear: UIImage? = UIImage(named: "ic_close_white", inBundle: NSBundle(identifier: "io.cosmicmind.Material"), compatibleWithTraitCollection: nil)?.imageWithRenderingMode(.AlwaysTemplate)
public static let close: UIImage? = UIImage(named: "ic_close_white", inBundle: NSBundle(identifier: "io.cosmicmind.Material"), compatibleWithTraitCollection: nil)?.imageWithRenderingMode(.AlwaysTemplate)
public static let menu: UIImage? = UIImage(named: "ic_menu_white", inBundle: NSBundle(identifier: "io.cosmicmind.Material"), compatibleWithTraitCollection: nil)?.imageWithRenderingMode(.AlwaysTemplate)
public static let search: UIImage? = UIImage(named: "ic_search_white", inBundle: NSBundle(identifier: "io.cosmicmind.Material"), compatibleWithTraitCollection: nil)?.imageWithRenderingMode(.AlwaysTemplate)
public static let share: UIImage? = UIImage(named: "ic_share_white", inBundle: NSBundle(identifier: "io.cosmicmind.Material"), compatibleWithTraitCollection: nil)?.imageWithRenderingMode(.AlwaysTemplate)
}
...@@ -138,7 +138,7 @@ public class MaterialPulseView : MaterialView { ...@@ -138,7 +138,7 @@ public class MaterialPulseView : MaterialView {
} }
pulseLayer.addAnimation(MaterialAnimation.scale(3 * d, duration: t), forKey: nil) pulseLayer.addAnimation(MaterialAnimation.scale(3 * d, duration: t), forKey: nil)
MaterialAnimation.delay(t) { [weak self] in MaterialAnimation.delay(t) { [weak self] in
if nil != self && nil != self!.pulseColor && 0 < self!.pulseColorOpacity { if nil != self?.pulseColor && 0 < self?.pulseColorOpacity {
MaterialAnimation.animateWithDuration(t, animations: { MaterialAnimation.animateWithDuration(t, animations: {
pulseLayer.hidden = true pulseLayer.hidden = true
}) { }) {
......
...@@ -480,7 +480,7 @@ public class MaterialTableViewCell: UITableViewCell { ...@@ -480,7 +480,7 @@ public class MaterialTableViewCell: UITableViewCell {
} }
pulseLayer.addAnimation(MaterialAnimation.scale(3 * d, duration: t), forKey: nil) pulseLayer.addAnimation(MaterialAnimation.scale(3 * d, duration: t), forKey: nil)
MaterialAnimation.delay(t) { [weak self] in MaterialAnimation.delay(t) { [weak self] in
if nil != self && nil != self!.pulseColor && 0 < self!.pulseColorOpacity { if nil != self?.pulseColor && 0 < self?.pulseColorOpacity {
MaterialAnimation.animateWithDuration(t, animations: { MaterialAnimation.animateWithDuration(t, animations: {
pulseLayer.hidden = true pulseLayer.hidden = true
}) { }) {
......
...@@ -47,80 +47,28 @@ public class NavigationBar : UINavigationBar { ...@@ -47,80 +47,28 @@ public class NavigationBar : UINavigationBar {
public private(set) lazy var backButton: FlatButton = FlatButton() public private(set) lazy var backButton: FlatButton = FlatButton()
/** /**
A CAShapeLayer used to manage elements that would be affected by The back button image writes to the backIndicatorImage property and
the clipToBounds property of the backing layer. For example, this backIndicatorTransitionMaskImage property.
allows the dropshadow effect on the backing layer, while clipping
the image to a desired shape within the visualLayer.
*/
public private(set) lazy var visualLayer: CAShapeLayer = CAShapeLayer()
/**
A property that manages an image for the visualLayer's contents
property. Images should not be set to the backing layer's contents
property to avoid conflicts when using clipsToBounds.
*/ */
public var image: UIImage? { public var backButtonImage: UIImage? {
didSet { didSet {
visualLayer.contents = image?.CGImage if nil == backButtonImage {
} backButtonImage = MaterialIcon.arrowBack
}
/**
Allows a relative subrectangle within the range of 0 to 1 to be
specified for the visualLayer's contents property. This allows
much greater flexibility than the contentsGravity property in
terms of how the image is cropped and stretched.
*/
public var contentsRect: CGRect {
get {
return visualLayer.contentsRect
}
set(value) {
visualLayer.contentsRect = value
}
}
/**
A CGRect that defines a stretchable region inside the visualLayer
with a fixed border around the edge.
*/
public var contentsCenter: CGRect {
get {
return visualLayer.contentsCenter
}
set(value) {
visualLayer.contentsCenter = value
}
}
/**
A floating point value that defines a ratio between the pixel
dimensions of the visualLayer's contents property and the size
of the view. By default, this value is set to the MaterialDevice.scale.
*/
public var contentsScale: CGFloat {
get {
return visualLayer.contentsScale
} }
set(value) {
visualLayer.contentsScale = value
} }
} }
/// A Preset for the contentsGravity property. /// A preset for contentInset.
public var contentsGravityPreset: MaterialGravity { public var contentInsetPreset: MaterialEdgeInset = .None {
didSet { didSet {
contentsGravity = MaterialGravityToString(contentsGravityPreset) contentInset = MaterialEdgeInsetToValue(contentInsetPreset)
} }
} }
/// Determines how content should be aligned within the visualLayer's bounds. /// A UIEdgeInsets value for insetting the content.
public var contentsGravity: String { public var contentInset: UIEdgeInsets = MaterialEdgeInsetToValue(.None) {
get { didSet {
return visualLayer.contentsGravity layoutSubviews()
}
set(value) {
visualLayer.contentsGravity = value
} }
} }
...@@ -139,18 +87,6 @@ public class NavigationBar : UINavigationBar { ...@@ -139,18 +87,6 @@ public class NavigationBar : UINavigationBar {
} }
} }
/**
The back button image writes to the backIndicatorImage property and
backIndicatorTransitionMaskImage property.
*/
public var backButtonImage: UIImage? {
didSet {
if nil == backButtonImage {
backButtonImage = UIImage(named: "ic_arrow_back_white", inBundle: NSBundle(identifier: "io.cosmicmind.Material"), compatibleWithTraitCollection: nil)
}
}
}
/// A property that accesses the backing layer's backgroundColor. /// A property that accesses the backing layer's backgroundColor.
public override var backgroundColor: UIColor? { public override var backgroundColor: UIColor? {
didSet { didSet {
...@@ -259,25 +195,6 @@ public class NavigationBar : UINavigationBar { ...@@ -259,25 +195,6 @@ public class NavigationBar : UINavigationBar {
} }
} }
/// A property that sets the cornerRadius of the backing layer.
public var cornerRadiusPreset: MaterialRadius = .None {
didSet {
if let v: MaterialRadius = cornerRadiusPreset {
cornerRadius = MaterialRadiusToValue(v)
}
}
}
/// A property that accesses the layer.cornerRadius.
public var cornerRadius: CGFloat {
get {
return layer.cornerRadius
}
set(value) {
layer.cornerRadius = value
}
}
/// A preset property to set the borderWidth. /// A preset property to set the borderWidth.
public var borderWidthPreset: MaterialBorder = .None { public var borderWidthPreset: MaterialBorder = .None {
didSet { didSet {
...@@ -305,32 +222,11 @@ public class NavigationBar : UINavigationBar { ...@@ -305,32 +222,11 @@ public class NavigationBar : UINavigationBar {
} }
} }
/// A property that accesses the layer.position property.
public var position: CGPoint {
get {
return layer.position
}
set(value) {
layer.position = value
}
}
/// A property that accesses the layer.zPosition property.
public var zPosition: CGFloat {
get {
return layer.zPosition
}
set(value) {
layer.zPosition = value
}
}
/** /**
An initializer that initializes the object with a NSCoder object. An initializer that initializes the object with a NSCoder object.
- Parameter aDecoder: A NSCoder instance. - Parameter aDecoder: A NSCoder instance.
*/ */
public required init?(coder aDecoder: NSCoder) { public required init?(coder aDecoder: NSCoder) {
contentsGravityPreset = .ResizeAspectFill
super.init(coder: aDecoder) super.init(coder: aDecoder)
prepareView() prepareView()
} }
...@@ -342,7 +238,6 @@ public class NavigationBar : UINavigationBar { ...@@ -342,7 +238,6 @@ public class NavigationBar : UINavigationBar {
- Parameter frame: A CGRect instance. - Parameter frame: A CGRect instance.
*/ */
public override init(frame: CGRect) { public override init(frame: CGRect) {
contentsGravityPreset = .ResizeAspectFill
super.init(frame: frame) super.init(frame: frame)
prepareView() prepareView()
} }
...@@ -352,76 +247,106 @@ public class NavigationBar : UINavigationBar { ...@@ -352,76 +247,106 @@ public class NavigationBar : UINavigationBar {
self.init(frame: CGRectNull) self.init(frame: CGRectNull)
} }
/// Overriding the layout callback for sublayers.
public override func layoutSublayersOfLayer(layer: CALayer) {
super.layoutSublayersOfLayer(layer)
if self.layer == layer {
layoutVisualLayer()
}
}
public override func layoutSubviews() { public override func layoutSubviews() {
super.layoutSubviews() super.layoutSubviews()
/* if let item: UINavigationItem = topItem {
When rotating the device orientation, this adjusts the layout layoutNavigationItem(item)
of the titleView subviews. }
*/
topItem?.titleView?.grid.reloadLayout() topItem?.titleView?.grid.reloadLayout()
} }
public override func pushNavigationItem(item: UINavigationItem, animated: Bool) {
super.pushNavigationItem(item, animated: animated)
layoutNavigationItem(item)
}
/**
Lays out the UINavigationItem.
- Parameter item: A UINavigationItem to layout.
*/
public func layoutNavigationItem(item: UINavigationItem) { public func layoutNavigationItem(item: UINavigationItem) {
prepareItem(item)
let h: CGFloat = intrinsicContentSize().height
let w: CGFloat = backButton.intrinsicContentSize().width
let inset: CGFloat = MaterialDevice.landscape ? item.landscapeInset : item.portraitInset
// leftControls // leftControls
if let v: Array<UIControl> = item.leftControls { if let v: Array<UIControl> = item.leftControls {
var n: Array<UIBarButtonItem> = Array<UIBarButtonItem>() var n: Array<UIBarButtonItem> = Array<UIBarButtonItem>()
for c in v { for c in v {
c.bounds.size = c is MaterialSwitch ? backButton.bounds.size : c.intrinsicContentSize() if let b: UIButton = c as? UIButton {
b.contentEdgeInsets.top = 0
b.contentEdgeInsets.bottom = 0
}
c.bounds.size = c is MaterialSwitch ? CGSizeMake(w, h - contentInset.top - contentInset.bottom) : CGSizeMake(c.intrinsicContentSize().width, h - contentInset.top - contentInset.bottom)
n.append(UIBarButtonItem(customView: c)) n.append(UIBarButtonItem(customView: c))
} }
// The spacer moves the UIBarButtonItems to the edge of the UINavigationBar.
let spacer: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: .FixedSpace, target: nil, action: nil) let spacer: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: .FixedSpace, target: nil, action: nil)
spacer.width = item.inset spacer.width = inset + contentInset.left
n.append(spacer) n.append(spacer)
item.leftBarButtonItems = n.reverse() item.leftBarButtonItems = n.reverse()
} }
if nil == item.titleView { if nil == item.titleView {
item.titleView = UIView(frame: CGRectMake(0, 0, 2000, 44)) item.titleView = UIView()
item.titleView!.backgroundColor = nil item.titleView!.backgroundColor = nil
item.titleView!.grid.axis.direction = .Vertical item.titleView!.grid.axis.direction = .Vertical
} }
item.titleView!.frame = CGRectMake(0, contentInset.top, MaterialDevice.width < MaterialDevice.height ? MaterialDevice.height : MaterialDevice.width, h - contentInset.top - contentInset.bottom)
item.titleView!.grid.views = [] item.titleView!.grid.views = []
// TitleView alignment. // TitleView alignment.
if let t: UILabel = item.titleLabel { if let t: UILabel = item.titleLabel {
t.grid.rows = 1 t.grid.rows = 1
t.backgroundColor = MaterialColor.red.accent1
item.titleView!.addSubview(t) item.titleView!.addSubview(t)
item.titleView!.grid.views?.append(t) item.titleView!.grid.views?.append(t)
if let d: UILabel = item.detailLabel {
d.backgroundColor = MaterialColor.red.accent3 if 32 >= height || nil == item.detailLabel {
t.font = t.font.fontWithSize(17) t.font = t.font?.fontWithSize(20)
item.titleView!.grid.axis.rows = 1
item.detailLabel?.hidden = true
} else if let d: UILabel = item.detailLabel {
d.grid.rows = 1 d.grid.rows = 1
d.hidden = false
d.font = d.font.fontWithSize(12) d.font = d.font.fontWithSize(12)
t.font = t.font.fontWithSize(17)
item.titleView!.addSubview(d) item.titleView!.addSubview(d)
item.titleView!.grid.views?.append(d)
item.titleView!.grid.axis.rows = 2 item.titleView!.grid.axis.rows = 2
} else { item.titleView!.grid.views?.append(d)
t.font = t.font?.fontWithSize(20)
item.titleView!.grid.axis.rows = 1
} }
} else if let d: UIView = item.detailView {
d.grid.rows = 1
item.titleView!.addSubview(d)
item.titleView!.grid.axis.rows = 1
item.titleView!.grid.views?.append(d)
} }
// rightControls // rightControls
if let v: Array<UIControl> = item.rightControls { if let v: Array<UIControl> = item.rightControls {
var n: Array<UIBarButtonItem> = Array<UIBarButtonItem>() var n: Array<UIBarButtonItem> = Array<UIBarButtonItem>()
for c in v { for c in v {
c.bounds.size = c is MaterialSwitch ? backButton.bounds.size : c.intrinsicContentSize() if let b: UIButton = c as? UIButton {
b.contentEdgeInsets.top = 0
b.contentEdgeInsets.bottom = 0
}
c.bounds.size = c is MaterialSwitch ? CGSizeMake(w, h - contentInset.top - contentInset.bottom) : CGSizeMake(c.intrinsicContentSize().width, h - contentInset.top - contentInset.bottom)
n.append(UIBarButtonItem(customView: c)) n.append(UIBarButtonItem(customView: c))
} }
// The spacer moves the UIBarButtonItems to the edge of the UINavigationBar.
let spacer: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: .FixedSpace, target: nil, action: nil) let spacer: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: .FixedSpace, target: nil, action: nil)
spacer.width = item.inset spacer.width = inset + contentInset.right
n.append(spacer) n.append(spacer)
item.rightBarButtonItems = n.reverse() item.rightBarButtonItems = n.reverse()
} }
...@@ -441,23 +366,10 @@ public class NavigationBar : UINavigationBar { ...@@ -441,23 +366,10 @@ public class NavigationBar : UINavigationBar {
backButtonImage = nil backButtonImage = nil
backgroundColor = MaterialColor.white backgroundColor = MaterialColor.white
depth = .Depth1 depth = .Depth1
prepareVisualLayer() contentInset = UIEdgeInsetsMake(2, 2, 2, 2)
prepareBackButton() prepareBackButton()
} }
/// Prepares the visualLayer property.
internal func prepareVisualLayer() {
visualLayer.zPosition = 0
visualLayer.masksToBounds = true
layer.addSublayer(visualLayer)
}
/// Manages the layout for the visualLayer property.
internal func layoutVisualLayer() {
visualLayer.frame = bounds
visualLayer.cornerRadius = cornerRadius
}
/// Prepares the backButton. /// Prepares the backButton.
internal func prepareBackButton() { internal func prepareBackButton() {
backButton.pulseScale = false backButton.pulseScale = false
...@@ -465,6 +377,11 @@ public class NavigationBar : UINavigationBar { ...@@ -465,6 +377,11 @@ public class NavigationBar : UINavigationBar {
backButton.setImage(backButtonImage, forState: .Normal) backButton.setImage(backButtonImage, forState: .Normal)
backButton.setImage(backButtonImage, forState: .Highlighted) backButton.setImage(backButtonImage, forState: .Highlighted)
} }
/// Prepares the UINavigationItem for layout and sizing.
internal func prepareItem(item: UINavigationItem) {
item.title = ""
}
} }
/// A memory reference to the NavigationItem instance for UINavigationBar extensions. /// A memory reference to the NavigationItem instance for UINavigationBar extensions.
...@@ -472,7 +389,12 @@ private var NavigationItemKey: UInt8 = 0 ...@@ -472,7 +389,12 @@ private var NavigationItemKey: UInt8 = 0
public class NavigationItem { public class NavigationItem {
/// Inset. /// Inset.
public var inset: CGFloat = -16 public var portraitInset: CGFloat = .iPad == MaterialDevice.type || "iPhone 6s Plus" == MaterialDevice.model || "iPhone 6 Plus" == MaterialDevice.model ? -20 : -16
public var landscapeInset: CGFloat = -20
/// Detail View.
public var detailView: UIView?
/// Title label. /// Title label.
public var titleLabel: UILabel? public var titleLabel: UILabel?
...@@ -500,13 +422,33 @@ public extension UINavigationItem { ...@@ -500,13 +422,33 @@ public extension UINavigationItem {
} }
} }
/// Inset. /// Portrait inset.
public var inset: CGFloat { public var portraitInset: CGFloat {
get {
return item.portraitInset
}
set(value) {
item.portraitInset = value
}
}
/// Landscape inset.
public var landscapeInset: CGFloat {
get {
return item.landscapeInset
}
set(value) {
item.landscapeInset = value
}
}
/// Detail View.
public var detailView: UIView? {
get { get {
return item.inset return item.detailView
} }
set(value) { set(value) {
item.inset = value item.detailView = value
} }
} }
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
import UIKit import UIKit
public class NavigationController : UINavigationController { public class NavigationController : UINavigationController, UIGestureRecognizerDelegate {
/** /**
An initializer that initializes the object with a NSCoder object. An initializer that initializes the object with a NSCoder object.
- Parameter aDecoder: A NSCoder instance. - Parameter aDecoder: A NSCoder instance.
...@@ -61,18 +61,35 @@ public class NavigationController : UINavigationController { ...@@ -61,18 +61,35 @@ public class NavigationController : UINavigationController {
super.viewDidLoad() super.viewDidLoad()
// This ensures the panning gesture is available when going back between views. // This ensures the panning gesture is available when going back between views.
interactivePopGestureRecognizer?.delegate = nil if let v: UIGestureRecognizer = interactivePopGestureRecognizer {
v.enabled = true
v.delegate = self
}
} }
public override func viewDidAppear(animated: Bool) { public override func viewWillAppear(animated: Bool) {
super.viewDidAppear(animated) super.viewWillAppear(animated)
if let v: UINavigationItem = navigationBar.topItem { if let v: UIGestureRecognizer = interactivePopGestureRecognizer {
prepareTitle(v) if let x: SideNavigationViewController = sideNavigationViewController {
(navigationBar as? NavigationBar)?.layoutNavigationItem(v) if let p: UIPanGestureRecognizer = x.panGesture {
p.requireGestureRecognizerToFail(v)
}
}
} }
} }
/** /**
Detects the gesture recognizer being used. This is necessary when using
SideNavigationViewController. It eliminates the conflict in panning.
- Parameter gestureRecognizer: A UIGestureRecognizer to detect.
- Parameter touch: The UITouch event.
- Returns: A Boolean of whether to continue the gesture or not, true yes, false no.
*/
public func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
return interactivePopGestureRecognizer == gestureRecognizer && nil != navigationBar.backItem
}
/**
Delegation method that is called when a new UINavigationItem is about to be pushed. Delegation method that is called when a new UINavigationItem is about to be pushed.
This is used to prepare the transitions between UIViewControllers on the stack. This is used to prepare the transitions between UIViewControllers on the stack.
- Parameter navigationBar: A UINavigationBar that is used in the NavigationController. - Parameter navigationBar: A UINavigationBar that is used in the NavigationController.
...@@ -82,7 +99,6 @@ public class NavigationController : UINavigationController { ...@@ -82,7 +99,6 @@ public class NavigationController : UINavigationController {
*/ */
public func navigationBar(navigationBar: UINavigationBar, shouldPushItem item: UINavigationItem) -> Bool { public func navigationBar(navigationBar: UINavigationBar, shouldPushItem item: UINavigationItem) -> Bool {
if let v: NavigationBar = navigationBar as? NavigationBar { if let v: NavigationBar = navigationBar as? NavigationBar {
prepareTitle(item)
item.setHidesBackButton(true, animated: false) item.setHidesBackButton(true, animated: false)
if var c: Array<UIControl> = item.leftControls { if var c: Array<UIControl> = item.leftControls {
c.append(v.backButton) c.append(v.backButton)
...@@ -97,15 +113,12 @@ public class NavigationController : UINavigationController { ...@@ -97,15 +113,12 @@ public class NavigationController : UINavigationController {
return true return true
} }
public func sideNavigationStatusBarHiddenState(sideNavigationViewController: SideNavigationViewController, hidden: Bool) {
print(hidden)
}
/// Handler for the back button. /// Handler for the back button.
internal func handleBackButton() { internal func handleBackButton() {
popViewControllerAnimated(true) popViewControllerAnimated(true)
} }
/// Prepares the title if it's value is nil.
private func prepareTitle(item: UINavigationItem) {
if nil == item.title {
item.title = ""
}
}
} }
...@@ -103,6 +103,12 @@ public protocol SideNavigationViewControllerDelegate { ...@@ -103,6 +103,12 @@ public protocol SideNavigationViewControllerDelegate {
SideNavigationViewController tap gesture executes. SideNavigationViewController tap gesture executes.
*/ */
optional func sideNavigationViewDidTap(sideNavigationViewController: SideNavigationViewController, point: CGPoint, position: SideNavigationPosition) optional func sideNavigationViewDidTap(sideNavigationViewController: SideNavigationViewController, point: CGPoint, position: SideNavigationPosition)
/**
An optional delegation method that is fired when the
status bar is about to change display, hidden or not.
*/
optional func sideNavigationStatusBarHiddenState(sideNavigationViewController: SideNavigationViewController, hidden: Bool)
} }
@objc(SideNavigationViewController) @objc(SideNavigationViewController)
...@@ -117,13 +123,13 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer ...@@ -117,13 +123,13 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
A UIPanGestureRecognizer property internally used for the A UIPanGestureRecognizer property internally used for the
pan gesture. pan gesture.
*/ */
private var panGesture: UIPanGestureRecognizer? internal var panGesture: UIPanGestureRecognizer?
/** /**
A UITapGestureRecognizer property internally used for the A UITapGestureRecognizer property internally used for the
tap gesture. tap gesture.
*/ */
private var tapGesture: UITapGestureRecognizer? internal var tapGesture: UITapGestureRecognizer?
/** /**
A CGFloat property that accesses the leftView threshold of A CGFloat property that accesses the leftView threshold of
...@@ -192,29 +198,13 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer ...@@ -192,29 +198,13 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
A Boolean property that enables and disables the leftView from A Boolean property that enables and disables the leftView from
opening and closing. Defaults to true. opening and closing. Defaults to true.
*/ */
public var enabledLeftView: Bool = false { public var enabledLeftView: Bool = false
didSet {
if enabledLeftView {
prepareGestures(panSelector: "handlePanGesture:", tapSelector: "handleTapGesture:")
} else if !enabledRightView {
removeGestures()
}
}
}
/** /**
A Boolean property that enables and disables the rightView from A Boolean property that enables and disables the rightView from
opening and closing. Defaults to true. opening and closing. Defaults to true.
*/ */
public var enabledRightView: Bool = false { public var enabledRightView: Bool = false
didSet {
if enabledRightView {
prepareGestures(panSelector: "handlePanGesture:", tapSelector: "handleTapGesture:")
} else if !enabledLeftView {
removeGestures()
}
}
}
/** /**
A Boolean property that triggers the status bar to be hidden A Boolean property that triggers the status bar to be hidden
...@@ -597,6 +587,12 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer ...@@ -597,6 +587,12 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
} }
} }
/**
Detects the gesture recognizer being used.
- Parameter gestureRecognizer: A UIGestureRecognizer to detect.
- Parameter touch: The UITouch event.
- Returns: A Boolean of whether to continue the gesture or not.
*/
public func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool { public func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
if gestureRecognizer == panGesture { if gestureRecognizer == panGesture {
return opened || isPointContainedWithinLeftViewThreshold(touch.locationInView(view)) || isPointContainedWithinRightViewThreshold(touch.locationInView(view)) return opened || isPointContainedWithinLeftViewThreshold(touch.locationInView(view)) || isPointContainedWithinRightViewThreshold(touch.locationInView(view))
...@@ -721,7 +717,7 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer ...@@ -721,7 +717,7 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
prepareRightView() prepareRightView()
prepareLeftViewController() prepareLeftViewController()
prepareRightViewController() prepareRightViewController()
enabled = true prepareGestures()
} }
/// A method that prepares the mainViewController. /// A method that prepares the mainViewController.
...@@ -799,20 +795,16 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer ...@@ -799,20 +795,16 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
/** /**
A method that prepares the gestures used within the A method that prepares the gestures used within the
SideNavigationViewController. SideNavigationViewController.
- Parameter panSelector: A Selector that is fired when the
pan gesture is recognized.
- Parameter tapSelector: A Selector that is fired when the
tap gesture is recognized.
*/ */
private func prepareGestures(panSelector panSelector: Selector, tapSelector: Selector) { private func prepareGestures() {
if nil == panGesture { if nil == panGesture {
panGesture = UIPanGestureRecognizer(target: self, action: panSelector) panGesture = UIPanGestureRecognizer(target: self, action: "handlePanGesture:")
panGesture!.delegate = self panGesture!.delegate = self
view.addGestureRecognizer(panGesture!) view.addGestureRecognizer(panGesture!)
} }
if nil == tapGesture { if nil == tapGesture {
tapGesture = UITapGestureRecognizer(target: self, action: tapSelector) tapGesture = UITapGestureRecognizer(target: self, action: "handleTapGesture:")
tapGesture!.cancelsTouchesInView = false tapGesture!.cancelsTouchesInView = false
tapGesture!.delegate = self tapGesture!.delegate = self
view.addGestureRecognizer(tapGesture!) view.addGestureRecognizer(tapGesture!)
...@@ -843,15 +835,23 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer ...@@ -843,15 +835,23 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
*/ */
private func toggleStatusBar(hide: Bool = false) { private func toggleStatusBar(hide: Bool = false) {
if hideStatusBar { if hideStatusBar {
UIView.animateWithDuration(0.25, animations: { [weak self] in userInteractionEnabled = false
// General alignment. let hidden: Bool = .iPhone == MaterialDevice.type && MaterialDevice.landscape || opened ? true : hide
if .iPhone == MaterialDevice.type && MaterialDevice.landscape { UIView.animateWithDuration(NSTimeInterval(UINavigationControllerHideShowBarDuration),
UIApplication.sharedApplication().statusBarHidden = true animations: { [weak self] in
} else { self?.setNeedsStatusBarAppearanceUpdate()
UIApplication.sharedApplication().statusBarHidden = true == self?.opened ? true : hide UIApplication.sharedApplication().statusBarHidden = hidden
}) { [weak self] _ in
if false == self?.opened {
self?.userInteractionEnabled = true
} }
})
} }
delegate?.sideNavigationStatusBarHiddenState?(self, hidden: hidden)
}
}
public override func preferredStatusBarUpdateAnimation() -> UIStatusBarAnimation {
return .Fade
} }
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment