Commit 257c19c2 by prateeksan

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

parents 7fbd3d7f dd913a42
......@@ -47,6 +47,9 @@
location = "group:Programmatic/MenuViewController/MenuViewController.xcodeproj">
</FileRef>
<FileRef
location = "group:Programmatic/NavigationBar/NavigationBar.xcodeproj">
</FileRef>
<FileRef
location = "group:Programmatic/SearchBarView/SearchBarView.xcodeproj">
</FileRef>
<FileRef
......
......@@ -19,8 +19,7 @@
9663F94E1C7A74EA00AF0965 /* AppLeftViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9663F94D1C7A74EA00AF0965 /* AppLeftViewController.swift */; };
9663F9501C7A74FC00AF0965 /* AppRightViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9663F94F1C7A74FC00AF0965 /* AppRightViewController.swift */; };
9663F9521C7A751D00AF0965 /* FeedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9663F9511C7A751D00AF0965 /* FeedViewController.swift */; };
96CC08881C7FEBD60034FF84 /* InboxViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96CC08871C7FEBD60034FF84 /* InboxViewController.swift */; };
96FC37D31C8CE1290040A569 /* MessagesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96FC37D21C8CE1290040A569 /* MessagesViewController.swift */; };
96CC08881C7FEBD60034FF84 /* RecipesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96CC08871C7FEBD60034FF84 /* RecipesViewController.swift */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
......@@ -51,8 +50,7 @@
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>"; };
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>"; };
96FC37D21C8CE1290040A569 /* MessagesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessagesViewController.swift; sourceTree = "<group>"; };
96CC08871C7FEBD60034FF84 /* RecipesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipesViewController.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
......@@ -95,8 +93,7 @@
9663F94F1C7A74FC00AF0965 /* AppRightViewController.swift */,
9663F9331C7A744600AF0965 /* SearchListViewController.swift */,
9663F9511C7A751D00AF0965 /* FeedViewController.swift */,
96CC08871C7FEBD60034FF84 /* InboxViewController.swift */,
96FC37D21C8CE1290040A569 /* MessagesViewController.swift */,
96CC08871C7FEBD60034FF84 /* RecipesViewController.swift */,
9663F9381C7A744600AF0965 /* Assets.xcassets */,
9663F93A1C7A744600AF0965 /* LaunchScreen.storyboard */,
9663F93D1C7A744600AF0965 /* Info.plist */,
......@@ -175,9 +172,8 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
96FC37D31C8CE1290040A569 /* MessagesViewController.swift in Sources */,
9663F94A1C7A74B500AF0965 /* AppSearchBarViewController.swift in Sources */,
96CC08881C7FEBD60034FF84 /* InboxViewController.swift in Sources */,
96CC08881C7FEBD60034FF84 /* RecipesViewController.swift in Sources */,
9663F9501C7A74FC00AF0965 /* AppRightViewController.swift in Sources */,
9663F9481C7A749400AF0965 /* AppNavigationController.swift in Sources */,
9663F9341C7A744600AF0965 /* SearchListViewController.swift in Sources */,
......
......@@ -39,7 +39,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
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!.makeKeyAndVisible()
return true
......
......@@ -76,7 +76,7 @@ class AppLeftViewController: UIViewController {
/// Prepares the items that are displayed within the tableView.
private func prepareCells() {
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.
......
......@@ -45,99 +45,3 @@ class AppNavigationController: NavigationController {
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 {
/// Prepares the items that are displayed within the tableView.
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: "Bookmarks", imageName: "ic_book"))
items.append(Item(text: "Work", imageName: "ic_work"))
......
......@@ -87,7 +87,7 @@ class AppSearchBarViewController: SearchBarViewController {
clearButton.setImage(image, forState: .Highlighted)
// Back button.
image = UIImage(named: "ic_arrow_back_white")?.imageWithRenderingMode(.AlwaysTemplate)
image = MaterialIcon.arrowDownward
let backButton: FlatButton = FlatButton()
backButton.pulseScale = false
backButton.pulseColor = MaterialColor.grey.darken4
......@@ -112,10 +112,11 @@ class AppSearchBarViewController: SearchBarViewController {
searchBarView.placeholderTextColor = MaterialColor.grey.darken4
searchBarView.textField.font = RobotoFont.regular
searchBarView.textField.delegate = self
searchBarView.contentInset.left = 8
searchBarView.contentInset.right = 8
searchBarView.clearButton = clearButton
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
import Material
class FeedViewController: UIViewController {
/// Menu button at the top left of the navigation bar.
private lazy var menuButton: FlatButton = FlatButton()
/// NavigationBar title label.
private var titleLabel: UILabel!
/// Search button at the top left of the navigation bar.
private lazy var searchButton: FlatButton = FlatButton()
/// NavigationBar menu button.
private var menuButton: FlatButton!
/// NavigationBar switch control.
private var switchControl: MaterialSwitch!
/// NavigationBar search button.
private var searchButton: FlatButton!
/// MaterialCollectionView.
private lazy var collectionView: MaterialCollectionView = MaterialCollectionView()
private var collectionView: MaterialCollectionView!
/// Image thumbnail height.
private var thumbnailHieght: CGFloat = 112
override func viewDidLoad() {
super.viewDidLoad()
prepareView()
prepareTitleLabel()
prepareMenuButton()
prepareSwitchControl()
prepareSearchButton()
prepareNavigationBar()
prepareCollectionView()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
// Ensure that the SideNavigation is enabled.
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) {
......@@ -66,32 +87,32 @@ class FeedViewController: UIViewController {
/// Handler for searchButton.
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() {
view.backgroundColor = MaterialColor.grey.lighten4
let titleLabel: UILabel = UILabel()
titleLabel.text = "Material"
titleLabel.textAlignment = .Left
titleLabel.textColor = MaterialColor.white
let detailLabel: UILabel = UILabel()
detailLabel.text = "Build Beautiful Software"
detailLabel.textAlignment = .Left
detailLabel.textColor = MaterialColor.white
}
/// Prepares view.
private func prepareNavigationBar() {
navigationItem.titleLabel = titleLabel
navigationItem.detailLabel = detailLabel
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.
private func prepareMenuButton() {
let image: UIImage? = UIImage(named: "ic_menu_white")
let image: UIImage? = MaterialIcon.menu
menuButton = FlatButton()
menuButton.pulseScale = false
menuButton.pulseColor = MaterialColor.white
menuButton.setImage(image, forState: .Normal)
......@@ -99,10 +120,15 @@ class FeedViewController: UIViewController {
menuButton.addTarget(self, action: "handleMenuButton", forControlEvents: .TouchUpInside)
}
/// Prepares the switchControl.
private func prepareSwitchControl() {
switchControl = MaterialSwitch(state: .Off, style: .LightContent, size: .Small)
}
/// Prepares the searchButton.
private func prepareSearchButton() {
// Search button.
let image: UIImage? = UIImage(named: "ic_search_white")
let image: UIImage? = MaterialIcon.search
searchButton = FlatButton()
searchButton.pulseScale = false
searchButton.pulseColor = MaterialColor.white
searchButton.setImage(image, forState: .Normal)
......@@ -110,13 +136,16 @@ class FeedViewController: UIViewController {
searchButton.addTarget(self, action: "handleSearchButton", forControlEvents: .TouchUpInside)
}
/// Prepares the collectionView
/// Prepares the collectionView.
private func prepareCollectionView() {
collectionView = MaterialCollectionView()
collectionView.dataSource = self
collectionView.delegate = self
collectionView.spacingPreset = .Spacing1
collectionView.contentInsetPreset = .Square1
collectionView.registerClass(MaterialCollectionViewCell.self, forCellWithReuseIdentifier: "MaterialCollectionViewCell")
// Layout the collectionView.
view.addSubview(collectionView)
collectionView.translatesAutoresizingMaskIntoConstraints = false
MaterialLayout.alignToParent(view, child: collectionView)
......@@ -131,49 +160,55 @@ extension FeedViewController: MaterialCollectionViewDataSource {
data: [
"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.",
"date": "February 26, 2016"
"date": "February 26, 2016",
"image": "AssortmentOfDessert"
],
height: 158
height: thumbnailHieght
),
MaterialDataSourceItem(
data: [
"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.",
"date": "February 26, 2016"
"date": "February 26, 2016",
"image": "AssortmentOfFood"
],
height: 158
height: thumbnailHieght
),
MaterialDataSourceItem(
data: [
"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.",
"date": "February 26, 2016"
"date": "February 26, 2016",
"image": "AvocadoIceCream"
],
height: 158
height: thumbnailHieght
),
MaterialDataSourceItem(
data: [
"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.",
"date": "February 26, 2016"
"date": "February 26, 2016",
"image": "HeartCookies"
],
height: 158
height: thumbnailHieght
),
MaterialDataSourceItem(
data: [
"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.",
"date": "February 26, 2016"
"date": "February 26, 2016",
"image": "VeganHempBalls"
],
height: 158
height: thumbnailHieght
),
MaterialDataSourceItem(
data: [
"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.",
"date": "February 26, 2016"
"date": "February 26, 2016",
"image": "VeganPieAbove"
],
height: 158
height: thumbnailHieght
)
]
}
......@@ -190,42 +225,42 @@ extension FeedViewController: MaterialCollectionViewDataSource {
/// Retrieves a 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]
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.
if nil == cardView {
cardView = CardView()
c.backgroundColor = nil
c.pulseColor = nil
c.contentView.addSubview(cardView!)
cell.backgroundColor = nil
cell.pulseColor = nil
cell.contentView.addSubview(cardView!)
cardView!.pulseScale = false
cardView!.divider = false
cardView!.depth = .None
cardView!.contentsGravityPreset = .Left
cardView!.contentInsetPreset = .Square3
cardView!.contentInset.bottom /= 2
cardView!.cornerRadiusPreset = .None
cardView!.cornerRadiusPreset = .Radius1
cardView!.rightButtonsInset.right = -8
let titleLabel: UILabel = UILabel()
titleLabel.textColor = MaterialColor.grey.darken4
titleLabel.font = RobotoFont.regularWithSize(18)
titleLabel.text = data["title"] as? String
cardView!.titleLabel = titleLabel
cardView!.titleLabelInset.left = 120
let detailLabel: UILabel = UILabel()
detailLabel.numberOfLines = 2
detailLabel.textColor = MaterialColor.grey.darken2
detailLabel.font = RobotoFont.regular
detailLabel.text = data["detail"] as? String
cardView!.detailView = detailLabel
cardView!.detailViewInset.left = 120
let image: UIImage? = UIImage(named: "ic_share_white_18pt")?.imageWithRenderingMode(.AlwaysTemplate)
......@@ -237,16 +272,27 @@ extension FeedViewController: MaterialCollectionViewDataSource {
shareButton.setImage(image, forState: .Highlighted)
cardView!.rightButtons = [shareButton]
c.contentView.addSubview(cardView!)
} else {
cardView?.titleLabel?.text = data["title"] as? String
(cardView?.detailView as? UILabel)?.text = data["detail"] as? String
cell.contentView.addSubview(cardView!)
}
// Add the data to the cardView.
cardView?.titleLabel?.text = data["title"] 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 {
extension FeedViewController: MaterialCollectionViewDelegate {
/// Executed when an item is selected.
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 {
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.
private let tableView: UITableView = UITableView()
private var tableView: UITableView!
/// A list of all the Author Bond types.
private var items: Array<Item> = Array<Item>()
private var items: Array<Item>!
override func viewDidLoad() {
super.viewDidLoad()
prepareItems()
prepareView()
prepareTitleLabel()
prepareDetailLabel()
prepareShareButton()
prepareNavigationBar()
prepareTableView()
}
......@@ -68,23 +80,12 @@ class MessagesViewController: UIViewController {
private func prepareView() {
view.backgroundColor = MaterialColor.white
let titleLabel: UILabel = UILabel()
titleLabel.text = "Messages"
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)
navigationItem.titleLabel = titleLabel
navigationItem.detailLabel = detailLabel
}
/// Prepares the NavigationBar.
private func prepareNavigationBar() {
navigationItem.titleLabel = titleLabel
navigationItem.detailLabel = detailLabel
navigationItem.rightControls = [shareButton]
......@@ -92,6 +93,7 @@ class MessagesViewController: UIViewController {
/// Prepares the items Array.
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: "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")))
......@@ -104,6 +106,7 @@ class MessagesViewController: UIViewController {
/// Prepares the tableView.
private func prepareTableView() {
tableView = UITableView()
tableView.registerClass(MaterialTableViewCell.self, forCellReuseIdentifier: "MaterialTableViewCell")
tableView.dataSource = self
tableView.delegate = self
......@@ -113,10 +116,36 @@ class MessagesViewController: UIViewController {
tableView.translatesAutoresizingMaskIntoConstraints = false
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.
extension MessagesViewController: UITableViewDataSource {
extension RecipesViewController: UITableViewDataSource {
/// Determines the number of rows in the tableView.
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count;
......@@ -163,7 +192,7 @@ extension MessagesViewController: UITableViewDataSource {
}
/// UITableViewDelegate methods.
extension MessagesViewController: UITableViewDelegate {
extension RecipesViewController: UITableViewDelegate {
/// Sets the tableView cell height.
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 80
......
......@@ -38,6 +38,9 @@ private struct Item {
}
class SearchListViewController: UIViewController {
/// TextField for search.
private let textField: TextField = TextField()
/// A tableView used to display Bond entries.
private let tableView: UITableView = UITableView()
......@@ -51,6 +54,15 @@ class SearchListViewController: UIViewController {
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
SideNavigationViewController.
......@@ -62,6 +74,30 @@ class SearchListViewController: UIViewController {
/// Prepares view.
private func prepareView() {
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.
......
// !$*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 @@
96A71F451C74ABCB00C0C4AE /* MaterialBorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96A71F441C74ABCB00C0C4AE /* MaterialBorder.swift */; };
96A71FB31C764E3200C0C4AE /* StatusBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96A71FB21C764E3200C0C4AE /* StatusBarView.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, ); }; };
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, ); }; };
......@@ -185,6 +186,7 @@
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>"; };
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>"; };
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>"; };
......@@ -349,6 +351,14 @@
name = Switch;
sourceTree = "<group>";
};
96BE340D1C8E68BB007D02BE /* Icon */ = {
isa = PBXGroup;
children = (
96BE340E1C8E68EF007D02BE /* MaterialIcon.swift */,
);
name = Icon;
sourceTree = "<group>";
};
96CC08561C7E0EC00034FF84 /* ControlView */ = {
isa = PBXGroup;
children = (
......@@ -376,6 +386,8 @@
96D88BFD1C1328D800B91418 /* LICENSE */,
96D88BFC1C1328D800B91418 /* Info.plist */,
96D88C091C1328D800B91418 /* Material.h */,
96334EF51C8B84660083986B /* Assets.xcassets */,
96BE340D1C8E68BB007D02BE /* Icon */,
96D88C501C132A2C00B91418 /* Extensions */,
96D88C531C132A6900B91418 /* View */,
96D88C521C132A5700B91418 /* Layout */,
......@@ -399,7 +411,6 @@
9626C2DB1C794FBB007CA8E0 /* SearchBar */,
9626C2DA1C794FA5007CA8E0 /* NavigationBar */,
9626C2DC1C794FE5007CA8E0 /* SideNavigation */,
96334EF51C8B84660083986B /* Assets.xcassets */,
);
path = Sources;
sourceTree = "<group>";
......@@ -754,6 +765,7 @@
96CC08921C7FEC170034FF84 /* MaterialCollectionView.swift in Sources */,
96A71EC71C6FFF0500C0C4AE /* MaterialSwitch.swift in Sources */,
96CC08951C7FEC170034FF84 /* MaterialCollectionViewDelegate.swift in Sources */,
96BE340F1C8E68EF007D02BE /* MaterialIcon.swift in Sources */,
96CC08971C7FEC170034FF84 /* MaterialDataSourceItem.swift in Sources */,
96D88C221C1328D800B91418 /* FabButton.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,15 +110,17 @@ public class ImageCardView : MaterialPulseView {
*/
public var maxImageHeight: CGFloat = 0 {
didSet {
if 0 < maxImageHeight {
prepareImageLayer()
let h: CGFloat = image!.size.height / contentsScale
imageLayer?.frame.size.height = maxImageHeight < h ? maxImageHeight : h
} else {
maxImageHeight = 0
imageLayer?.frame.size.height = nil == image ? 0 : image!.size.height / contentsScale
if let v: UIImage = image {
if 0 < maxImageHeight {
prepareImageLayer()
let h: CGFloat = v.size.height / contentsScale
imageLayer?.frame.size.height = maxImageHeight < h ? maxImageHeight : h
} else {
maxImageHeight = 0
imageLayer?.frame.size.height = nil == image ? 0 : v.size.height / contentsScale
}
reloadView()
}
reloadView()
}
}
......
......@@ -530,7 +530,7 @@ public class MaterialButton : UIButton {
}
pulseLayer.addAnimation(MaterialAnimation.scale(3 * d, duration: t), forKey: nil)
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: {
pulseLayer.hidden = true
}) {
......
......@@ -636,7 +636,7 @@ public class MaterialCollectionViewCell : UICollectionViewCell {
}
pulseLayer.addAnimation(MaterialAnimation.scale(3 * d, duration: t), forKey: nil)
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: {
pulseLayer.hidden = true
}) {
......
......@@ -38,6 +38,45 @@ public enum MaterialDeviceType {
}
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.
public static var type: MaterialDeviceType {
switch UIDevice.currentDevice().userInterfaceIdiom {
......@@ -47,7 +86,7 @@ public struct MaterialDevice {
return .iPhone
case .TV:
return .TV
case .Unspecified:
default:
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 {
}
pulseLayer.addAnimation(MaterialAnimation.scale(3 * d, duration: t), forKey: nil)
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: {
pulseLayer.hidden = true
}) {
......
......@@ -480,7 +480,7 @@ public class MaterialTableViewCell: UITableViewCell {
}
pulseLayer.addAnimation(MaterialAnimation.scale(3 * d, duration: t), forKey: nil)
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: {
pulseLayer.hidden = true
}) {
......
......@@ -47,80 +47,28 @@ public class NavigationBar : UINavigationBar {
public private(set) lazy var backButton: FlatButton = FlatButton()
/**
A CAShapeLayer used to manage elements that would be affected by
the clipToBounds property of the backing layer. For example, this
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.
The back button image writes to the backIndicatorImage property and
backIndicatorTransitionMaskImage property.
*/
public var image: UIImage? {
public var backButtonImage: UIImage? {
didSet {
visualLayer.contents = image?.CGImage
}
}
/**
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
if nil == backButtonImage {
backButtonImage = MaterialIcon.arrowBack
}
}
}
/// A Preset for the contentsGravity property.
public var contentsGravityPreset: MaterialGravity {
/// A preset for contentInset.
public var contentInsetPreset: MaterialEdgeInset = .None {
didSet {
contentsGravity = MaterialGravityToString(contentsGravityPreset)
contentInset = MaterialEdgeInsetToValue(contentInsetPreset)
}
}
/// Determines how content should be aligned within the visualLayer's bounds.
public var contentsGravity: String {
get {
return visualLayer.contentsGravity
}
set(value) {
visualLayer.contentsGravity = value
/// A UIEdgeInsets value for insetting the content.
public var contentInset: UIEdgeInsets = MaterialEdgeInsetToValue(.None) {
didSet {
layoutSubviews()
}
}
......@@ -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.
public override var backgroundColor: UIColor? {
didSet {
......@@ -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.
public var borderWidthPreset: MaterialBorder = .None {
didSet {
......@@ -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.
- Parameter aDecoder: A NSCoder instance.
*/
public required init?(coder aDecoder: NSCoder) {
contentsGravityPreset = .ResizeAspectFill
super.init(coder: aDecoder)
prepareView()
}
......@@ -342,7 +238,6 @@ public class NavigationBar : UINavigationBar {
- Parameter frame: A CGRect instance.
*/
public override init(frame: CGRect) {
contentsGravityPreset = .ResizeAspectFill
super.init(frame: frame)
prepareView()
}
......@@ -352,76 +247,106 @@ public class NavigationBar : UINavigationBar {
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() {
super.layoutSubviews()
/*
When rotating the device orientation, this adjusts the layout
of the titleView subviews.
*/
if let item: UINavigationItem = topItem {
layoutNavigationItem(item)
}
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) {
prepareItem(item)
let h: CGFloat = intrinsicContentSize().height
let w: CGFloat = backButton.intrinsicContentSize().width
let inset: CGFloat = MaterialDevice.landscape ? item.landscapeInset : item.portraitInset
// leftControls
if let v: Array<UIControl> = item.leftControls {
var n: Array<UIBarButtonItem> = Array<UIBarButtonItem>()
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))
}
// The spacer moves the UIBarButtonItems to the edge of the UINavigationBar.
let spacer: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: .FixedSpace, target: nil, action: nil)
spacer.width = item.inset
spacer.width = inset + contentInset.left
n.append(spacer)
item.leftBarButtonItems = n.reverse()
}
if nil == item.titleView {
item.titleView = UIView(frame: CGRectMake(0, 0, 2000, 44))
item.titleView = UIView()
item.titleView!.backgroundColor = nil
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 = []
// TitleView alignment.
if let t: UILabel = item.titleLabel {
t.grid.rows = 1
t.backgroundColor = MaterialColor.red.accent1
item.titleView!.addSubview(t)
item.titleView!.grid.views?.append(t)
if let d: UILabel = item.detailLabel {
d.backgroundColor = MaterialColor.red.accent3
t.font = t.font.fontWithSize(17)
if 32 >= height || nil == item.detailLabel {
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.hidden = false
d.font = d.font.fontWithSize(12)
t.font = t.font.fontWithSize(17)
item.titleView!.addSubview(d)
item.titleView!.grid.views?.append(d)
item.titleView!.grid.axis.rows = 2
} else {
t.font = t.font?.fontWithSize(20)
item.titleView!.grid.axis.rows = 1
item.titleView!.grid.views?.append(d)
}
} 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
if let v: Array<UIControl> = item.rightControls {
var n: Array<UIBarButtonItem> = Array<UIBarButtonItem>()
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))
}
// The spacer moves the UIBarButtonItems to the edge of the UINavigationBar.
let spacer: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: .FixedSpace, target: nil, action: nil)
spacer.width = item.inset
spacer.width = inset + contentInset.right
n.append(spacer)
item.rightBarButtonItems = n.reverse()
}
......@@ -441,23 +366,10 @@ public class NavigationBar : UINavigationBar {
backButtonImage = nil
backgroundColor = MaterialColor.white
depth = .Depth1
prepareVisualLayer()
contentInset = UIEdgeInsetsMake(2, 2, 2, 2)
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.
internal func prepareBackButton() {
backButton.pulseScale = false
......@@ -465,6 +377,11 @@ public class NavigationBar : UINavigationBar {
backButton.setImage(backButtonImage, forState: .Normal)
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.
......@@ -472,7 +389,12 @@ private var NavigationItemKey: UInt8 = 0
public class NavigationItem {
/// 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.
public var titleLabel: UILabel?
......@@ -500,13 +422,33 @@ public extension UINavigationItem {
}
}
/// Inset.
public var inset: CGFloat {
/// Portrait inset.
public var portraitInset: CGFloat {
get {
return item.inset
return item.portraitInset
}
set(value) {
item.inset = 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 {
return item.detailView
}
set(value) {
item.detailView = value
}
}
......@@ -549,4 +491,4 @@ public extension UINavigationItem {
item.rightControls = value
}
}
}
}
\ No newline at end of file
......@@ -30,7 +30,7 @@
import UIKit
public class NavigationController : UINavigationController {
public class NavigationController : UINavigationController, UIGestureRecognizerDelegate {
/**
An initializer that initializes the object with a NSCoder object.
- Parameter aDecoder: A NSCoder instance.
......@@ -61,18 +61,35 @@ public class NavigationController : UINavigationController {
super.viewDidLoad()
// 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) {
super.viewDidAppear(animated)
if let v: UINavigationItem = navigationBar.topItem {
prepareTitle(v)
(navigationBar as? NavigationBar)?.layoutNavigationItem(v)
public override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
if let v: UIGestureRecognizer = interactivePopGestureRecognizer {
if let x: SideNavigationViewController = sideNavigationViewController {
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.
This is used to prepare the transitions between UIViewControllers on the stack.
- Parameter navigationBar: A UINavigationBar that is used in the NavigationController.
......@@ -82,7 +99,6 @@ public class NavigationController : UINavigationController {
*/
public func navigationBar(navigationBar: UINavigationBar, shouldPushItem item: UINavigationItem) -> Bool {
if let v: NavigationBar = navigationBar as? NavigationBar {
prepareTitle(item)
item.setHidesBackButton(true, animated: false)
if var c: Array<UIControl> = item.leftControls {
c.append(v.backButton)
......@@ -97,15 +113,12 @@ public class NavigationController : UINavigationController {
return true
}
public func sideNavigationStatusBarHiddenState(sideNavigationViewController: SideNavigationViewController, hidden: Bool) {
print(hidden)
}
/// Handler for the back button.
internal func handleBackButton() {
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 {
SideNavigationViewController tap gesture executes.
*/
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)
......@@ -117,13 +123,13 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
A UIPanGestureRecognizer property internally used for the
pan gesture.
*/
private var panGesture: UIPanGestureRecognizer?
internal var panGesture: UIPanGestureRecognizer?
/**
A UITapGestureRecognizer property internally used for the
tap gesture.
*/
private var tapGesture: UITapGestureRecognizer?
internal var tapGesture: UITapGestureRecognizer?
/**
A CGFloat property that accesses the leftView threshold of
......@@ -192,29 +198,13 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
A Boolean property that enables and disables the leftView from
opening and closing. Defaults to true.
*/
public var enabledLeftView: Bool = false {
didSet {
if enabledLeftView {
prepareGestures(panSelector: "handlePanGesture:", tapSelector: "handleTapGesture:")
} else if !enabledRightView {
removeGestures()
}
}
}
public var enabledLeftView: Bool = false
/**
A Boolean property that enables and disables the rightView from
opening and closing. Defaults to true.
*/
public var enabledRightView: Bool = false {
didSet {
if enabledRightView {
prepareGestures(panSelector: "handlePanGesture:", tapSelector: "handleTapGesture:")
} else if !enabledLeftView {
removeGestures()
}
}
}
public var enabledRightView: Bool = false
/**
A Boolean property that triggers the status bar to be hidden
......@@ -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 {
if gestureRecognizer == panGesture {
return opened || isPointContainedWithinLeftViewThreshold(touch.locationInView(view)) || isPointContainedWithinRightViewThreshold(touch.locationInView(view))
......@@ -721,7 +717,7 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
prepareRightView()
prepareLeftViewController()
prepareRightViewController()
enabled = true
prepareGestures()
}
/// A method that prepares the mainViewController.
......@@ -799,20 +795,16 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
/**
A method that prepares the gestures used within the
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 {
panGesture = UIPanGestureRecognizer(target: self, action: panSelector)
panGesture = UIPanGestureRecognizer(target: self, action: "handlePanGesture:")
panGesture!.delegate = self
view.addGestureRecognizer(panGesture!)
}
if nil == tapGesture {
tapGesture = UITapGestureRecognizer(target: self, action: tapSelector)
tapGesture = UITapGestureRecognizer(target: self, action: "handleTapGesture:")
tapGesture!.cancelsTouchesInView = false
tapGesture!.delegate = self
view.addGestureRecognizer(tapGesture!)
......@@ -843,17 +835,25 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
*/
private func toggleStatusBar(hide: Bool = false) {
if hideStatusBar {
UIView.animateWithDuration(0.25, animations: { [weak self] in
// General alignment.
if .iPhone == MaterialDevice.type && MaterialDevice.landscape {
UIApplication.sharedApplication().statusBarHidden = true
} else {
UIApplication.sharedApplication().statusBarHidden = true == self?.opened ? true : hide
userInteractionEnabled = false
let hidden: Bool = .iPhone == MaterialDevice.type && MaterialDevice.landscape || opened ? true : hide
UIView.animateWithDuration(NSTimeInterval(UINavigationControllerHideShowBarDuration),
animations: { [weak self] in
self?.setNeedsStatusBarAppearanceUpdate()
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
}
/**
A method that determines whether the passed point is
contained within the bounds of the leftViewThreshold
......
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