Commit 18baf2bb by Daniel Dahan

development: updated Reminders sample project

parent 5108d65a
...@@ -35,19 +35,6 @@ class AppNavigationController: NavigationController { ...@@ -35,19 +35,6 @@ class AppNavigationController: NavigationController {
open override func prepare() { open override func prepare() {
super.prepare() super.prepare()
statusBarStyle = .default statusBarStyle = .default
// Sample preparation statements.
// prepareNavigationBar()
}
/// Prepares the navigationBar.
private func prepareNavigationBar() {
guard let v = navigationBar as? NavigationBar else {
return
}
v.depthPreset = .none
v.divider.color = Color.grey.lighten3
} }
} }
...@@ -8,18 +8,43 @@ ...@@ -8,18 +8,43 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
96784F381D901F610061C06C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96784F371D901F610061C06C /* AppDelegate.swift */; }; 96784F381D901F610061C06C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96784F371D901F610061C06C /* AppDelegate.swift */; };
96784F3A1D901F610061C06C /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96784F391D901F610061C06C /* ViewController.swift */; }; 96784F3A1D901F610061C06C /* RemindersListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96784F391D901F610061C06C /* RemindersListViewController.swift */; };
96784F3F1D901F610061C06C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 96784F3E1D901F610061C06C /* Assets.xcassets */; }; 96784F3F1D901F610061C06C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 96784F3E1D901F610061C06C /* Assets.xcassets */; };
96784F421D901F610061C06C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 96784F401D901F610061C06C /* LaunchScreen.storyboard */; }; 96784F421D901F610061C06C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 96784F401D901F610061C06C /* LaunchScreen.storyboard */; };
96784FD21D906CF10061C06C /* RemindersListCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96784FD11D906CF10061C06C /* RemindersListCollectionView.swift */; };
96784FD41D906D2F0061C06C /* RemindersListCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96784FD31D906D2F0061C06C /* RemindersListCollectionViewCell.swift */; };
96784FD61D906D780061C06C /* RemindersItemsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96784FD51D906D780061C06C /* RemindersItemsViewController.swift */; };
96784FD81D906DCB0061C06C /* RemindersItemsCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96784FD71D906DCB0061C06C /* RemindersItemsCollectionView.swift */; };
96784FDA1D906DF60061C06C /* RemindersItemsCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96784FD91D906DF60061C06C /* RemindersItemsCollectionViewCell.swift */; };
96784FDC1D906E190061C06C /* AppNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96784FDB1D906E190061C06C /* AppNavigationController.swift */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
96784FE01D906E940061C06C /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
96784F341D901F610061C06C /* RemindersController.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RemindersController.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96784F341D901F610061C06C /* RemindersController.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RemindersController.app; sourceTree = BUILT_PRODUCTS_DIR; };
96784F371D901F610061C06C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; 96784F371D901F610061C06C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
96784F391D901F610061C06C /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; }; 96784F391D901F610061C06C /* RemindersListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemindersListViewController.swift; sourceTree = "<group>"; };
96784F3E1D901F610061C06C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 96784F3E1D901F610061C06C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
96784F411D901F610061C06C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; 96784F411D901F610061C06C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
96784F431D901F610061C06C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 96784F431D901F610061C06C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
96784FD11D906CF10061C06C /* RemindersListCollectionView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RemindersListCollectionView.swift; sourceTree = "<group>"; };
96784FD31D906D2F0061C06C /* RemindersListCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RemindersListCollectionViewCell.swift; sourceTree = "<group>"; };
96784FD51D906D780061C06C /* RemindersItemsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RemindersItemsViewController.swift; sourceTree = "<group>"; };
96784FD71D906DCB0061C06C /* RemindersItemsCollectionView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RemindersItemsCollectionView.swift; sourceTree = "<group>"; };
96784FD91D906DF60061C06C /* RemindersItemsCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RemindersItemsCollectionViewCell.swift; sourceTree = "<group>"; };
96784FDB1D906E190061C06C /* AppNavigationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppNavigationController.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
...@@ -53,7 +78,13 @@ ...@@ -53,7 +78,13 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
96784F371D901F610061C06C /* AppDelegate.swift */, 96784F371D901F610061C06C /* AppDelegate.swift */,
96784F391D901F610061C06C /* ViewController.swift */, 96784FDB1D906E190061C06C /* AppNavigationController.swift */,
96784F391D901F610061C06C /* RemindersListViewController.swift */,
96784FD11D906CF10061C06C /* RemindersListCollectionView.swift */,
96784FD31D906D2F0061C06C /* RemindersListCollectionViewCell.swift */,
96784FD51D906D780061C06C /* RemindersItemsViewController.swift */,
96784FD71D906DCB0061C06C /* RemindersItemsCollectionView.swift */,
96784FD91D906DF60061C06C /* RemindersItemsCollectionViewCell.swift */,
96784F3E1D901F610061C06C /* Assets.xcassets */, 96784F3E1D901F610061C06C /* Assets.xcassets */,
96784F401D901F610061C06C /* LaunchScreen.storyboard */, 96784F401D901F610061C06C /* LaunchScreen.storyboard */,
96784F431D901F610061C06C /* Info.plist */, 96784F431D901F610061C06C /* Info.plist */,
...@@ -71,6 +102,7 @@ ...@@ -71,6 +102,7 @@
96784F301D901F610061C06C /* Sources */, 96784F301D901F610061C06C /* Sources */,
96784F311D901F610061C06C /* Frameworks */, 96784F311D901F610061C06C /* Frameworks */,
96784F321D901F610061C06C /* Resources */, 96784F321D901F610061C06C /* Resources */,
96784FE01D906E940061C06C /* Embed Frameworks */,
); );
buildRules = ( buildRules = (
); );
...@@ -132,8 +164,14 @@ ...@@ -132,8 +164,14 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
96784F3A1D901F610061C06C /* ViewController.swift in Sources */, 96784FD41D906D2F0061C06C /* RemindersListCollectionViewCell.swift in Sources */,
96784FDA1D906DF60061C06C /* RemindersItemsCollectionViewCell.swift in Sources */,
96784FD81D906DCB0061C06C /* RemindersItemsCollectionView.swift in Sources */,
96784F3A1D901F610061C06C /* RemindersListViewController.swift in Sources */,
96784F381D901F610061C06C /* AppDelegate.swift in Sources */, 96784F381D901F610061C06C /* AppDelegate.swift in Sources */,
96784FDC1D906E190061C06C /* AppNavigationController.swift in Sources */,
96784FD61D906D780061C06C /* RemindersItemsViewController.swift in Sources */,
96784FD21D906CF10061C06C /* RemindersListCollectionView.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
...@@ -248,6 +286,7 @@ ...@@ -248,6 +286,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = RemindersController/Info.plist; INFOPLIST_FILE = RemindersController/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = io.cosmicmind.RemindersController; PRODUCT_BUNDLE_IDENTIFIER = io.cosmicmind.RemindersController;
...@@ -260,6 +299,7 @@ ...@@ -260,6 +299,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = RemindersController/Info.plist; INFOPLIST_FILE = RemindersController/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = io.cosmicmind.RemindersController; PRODUCT_BUNDLE_IDENTIFIER = io.cosmicmind.RemindersController;
...@@ -287,6 +327,7 @@ ...@@ -287,6 +327,7 @@
96784F481D901F610061C06C /* Release */, 96784F481D901F610061C06C /* Release */,
); );
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
}; };
/* End XCConfigurationList section */ /* End XCConfigurationList section */
}; };
......
// /*
// AppDelegate.swift * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. <http://cosmicmind.io>.
// RemindersController * All rights reserved.
// *
// Created by Daniel Dahan on 2016-09-19. * Redistribution and use in source and binary forms, with or without
// Copyright © 2016 CosmicMind. All rights reserved. * 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 CosmicMind 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 UIKit
import Material
@UIApplicationMain @UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate { class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow? var window: UIWindow?
func applicationDidFinishLaunching(_ application: UIApplication) {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { window = UIWindow(frame: Device.bounds)
// Override point for customization after application launch. window!.rootViewController = AppNavigationController(rootViewController: RemindersListViewController())
return true window!.makeKeyAndVisible()
} }
func applicationWillResignActive(_ application: UIApplication) { func applicationWillResignActive(_ application: UIApplication) {
......
/*
* 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 CosmicMind 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 AppNavigationController: NavigationController {
open override func prepare() {
super.prepare()
statusBarStyle = .default
prepareNavigationBar()
}
/// Prepares the navigationBar.
private func prepareNavigationBar() {
guard let v = navigationBar as? NavigationBar else {
return
}
v.depthPreset = .none
v.divider.color = Color.grey.lighten3
}
}
...@@ -2,6 +2,10 @@ ...@@ -2,6 +2,10 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>NSRemindersUsageDescription</key>
<string>May I access your reminders?</string>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>en</string> <string>en</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
......
/*
* 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 CosmicMind 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 RemindersItemsCollectionView: UICollectionView {
override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
super.init(frame: frame, collectionViewLayout: layout)
prepare()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
prepare()
}
func prepare() {
register(RemindersItemsCollectionViewCell.self, forCellWithReuseIdentifier: "RemindersItemsCollectionViewCell")
}
}
/*
* 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 CosmicMind 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 RemindersItemsCollectionViewCell: CollectionViewCell {
/// A reference to the textLabel.
public private(set) lazy var textLabel: UILabel = UILabel()
/// A reference to the countLabel.
public private(set) lazy var countLabel: UILabel = UILabel()
open override func prepare() {
super.prepare()
prepareTextLabel()
prepareDivider()
}
/// Prepares the textLabel.
private func prepareTextLabel() {
textLabel.font = RobotoFont.regular
layout(textLabel).edges(top: 24, left: 24, bottom: 24, right: 24)
}
/// Prepares the divider.
private func prepareDivider() {
divider.color = Color.grey.lighten3
}
}
/*
* 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 CosmicMind 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 RemindersItemsViewController: UIViewController {
/// A reference to a DataSourceItem.
internal var dataSource: RemindersDataSource!
/// A reference to the dateFormatter.
internal var dateFormatter: DateFormatter!
/// A collectionView used to display entries.
internal var collectionView: RemindersItemsCollectionView!
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
init(dataSource: RemindersDataSource) {
super.init(nibName: nil, bundle: nil)
self.dataSource = dataSource
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = Color.grey.lighten5
prepareDateFormatter()
prepareNavigationItem()
prepareCollectionView()
}
private func prepareNavigationItem() {
navigationItem.title = dataSource.list.title
navigationItem.detail = dataSource.list.source.title
navigationItem.titleLabel.textColor = Color.blueGrey.base
navigationItem.detailLabel.textColor = Color.blueGrey.lighten1
}
/// Prepares the collectionView.
private func prepareCollectionView() {
let layout = UICollectionViewFlowLayout()
layout.minimumLineSpacing = 1
layout.minimumInteritemSpacing = 1
layout.scrollDirection = .vertical
layout.itemSize = CGSize(width: view.bounds.width, height: 88)
collectionView = RemindersItemsCollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.backgroundColor = Color.clear
collectionView.delegate = self
collectionView.dataSource = self
view.layout(collectionView).edges()
}
/// Prepares the dateFormatter.
private func prepareDateFormatter() {
dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .none
}
}
/// UICollectionViewDelegate methods.
extension RemindersItemsViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
}
}
/// CollectionViewDataSource methods.
extension RemindersItemsViewController: UICollectionViewDataSource {
/// Determines the number of items in the collectionView.
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
/// Returns the number of sections.
func numberOfSections(in collectionView: UICollectionView) -> Int {
return dataSource.items.count
}
/// Prepares the cells within the collectionView.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "RemindersItemsCollectionViewCell", for: indexPath) as! RemindersItemsCollectionViewCell
let item = dataSource.items[indexPath.section]
cell.textLabel.text = item.title
return cell
}
}
/*
* 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 CosmicMind 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 RemindersListCollectionView: UICollectionView {
override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
super.init(frame: frame, collectionViewLayout: layout)
prepare()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
prepare()
}
func prepare() {
register(RemindersListCollectionViewCell.self, forCellWithReuseIdentifier: "RemindersListCollectionViewCell")
}
}
/*
* 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 CosmicMind 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 RemindersListCollectionViewCell: CollectionViewCell {
/// A reference to the titleLabel.
public private(set) lazy var titleLabel: UILabel = UILabel()
/// A reference to the countLabel.
public private(set) lazy var countLabel: UILabel = UILabel()
open override func prepare() {
super.prepare()
prepareTitleLabel()
prepareCountLabel()
prepareDivider()
}
/// Prepares the titleLabel.
private func prepareTitleLabel() {
titleLabel.font = RobotoFont.regular(with: 22)
layout(titleLabel).edges(top: 24, left: 24, bottom: 24, right: 24)
}
/// Prepares the countLabel.
private func prepareCountLabel() {
countLabel.font = RobotoFont.regular(with: 22)
countLabel.textAlignment = .right
layout(countLabel).edges(top: 24, left: 24, bottom: 24, right: 24)
}
/// Prepares the divider.
private func prepareDivider() {
divider.color = Color.grey.lighten3
}
}
/*
* 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 CosmicMind 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
import EventKit
public struct RemindersDataSource {
/// A reference to an EKCalendar returned from the fetchResult.
public private(set) var list: EKCalendar
/// A reference to an Array of EKReminders for the EKCalendar.
public private(set) var items: [EKReminder]
}
class RemindersListViewController: RemindersController {
/// A collectionView used to display entries.
internal var collectionView: RemindersListCollectionView!
/// An Array of ReminderDataSource items.
internal lazy var dataSourceItems = [RemindersDataSource]()
open override func prepare() {
super.prepare()
view.backgroundColor = Color.grey.lighten5
prepareNavigationItem()
prepareCollectionView()
reminders.requestAuthorization()
}
private func prepareNavigationItem() {
navigationItem.title = "Reminders"
navigationItem.titleLabel.textColor = Color.blueGrey.base
navigationItem.detail = "Lists"
}
/// Prepares the collectionView.
private func prepareCollectionView() {
let layout = UICollectionViewFlowLayout()
layout.minimumLineSpacing = 1
layout.minimumInteritemSpacing = 1
layout.scrollDirection = .vertical
layout.itemSize = CGSize(width: view.bounds.width, height: 88)
collectionView = RemindersListCollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.backgroundColor = Color.clear
collectionView.delegate = self
collectionView.dataSource = self
view.layout(collectionView).edges()
}
}
extension RemindersListViewController {
func reminders(reminders: Reminders, status: RemindersAuthorizationStatus) {
print("Status", .authorized == status ? "Authorized" : "Denied")
}
func reminders(authorized reminders: Reminders) {
fetchLists { [weak self] in
self?.collectionView.reloadData()
}
}
func reminders(denied reminders: Reminders) {
print("Denied")
}
func reminders(reminders: Reminders, list: EKCalendar, created: Bool) {
}
func reminders(reminders: Reminders, list: EKCalendar, deleted: Bool) {
}
func reminders(reminders: Reminders, created: Bool) {
}
func reminders(reminders: Reminders, deleted: Bool) {
}
}
extension RemindersListViewController {
internal func fetchLists(completion: @escaping () -> Void) {
DispatchQueue.global(qos: .default).async { [weak self, completion = completion] in
guard let s = self else {
return
}
s.reminders.fetchLists { [weak self, completion = completion] (lists) in
guard let s = self else {
return
}
s.dataSourceItems.removeAll()
let endIndex = lists.count - 1
for i in 0...endIndex {
let list = lists[i]
s.reminders.fetchReminders(list: list) { [weak self, completion = completion] (reminders) in
guard let s = self else {
return
}
s.dataSourceItems.append(RemindersDataSource(list: list, items: reminders))
if i == endIndex {
completion()
}
}
}
}
}
}
}
/// UICollectionViewDelegate methods.
extension RemindersListViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
navigationController?.pushViewController(RemindersItemsViewController(dataSource: dataSourceItems[indexPath.section]), animated: true)
}
}
/// CollectionViewDataSource methods.
extension RemindersListViewController: UICollectionViewDataSource {
/// Determines the number of items in the collectionView.
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
/// Returns the number of sections.
func numberOfSections(in collectionView: UICollectionView) -> Int {
return dataSourceItems.count
}
/// Prepares the cells within the collectionView.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "RemindersListCollectionViewCell", for: indexPath) as! RemindersListCollectionViewCell
let dataSource = dataSourceItems[indexPath.section]
let list = dataSource.list
let items = dataSource.items
cell.titleLabel.text = list.title
cell.titleLabel.textColor = UIColor(cgColor: list.cgColor)
cell.countLabel.text = "\(items.count)"
cell.countLabel.textColor = UIColor(cgColor: list.cgColor)
return cell
}
}
//
// ViewController.swift
// RemindersController
//
// Created by Daniel Dahan on 2016-09-19.
// Copyright © 2016 CosmicMind. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
open override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
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