Verified Commit c09a5ea0 authored by Geoff Pado's avatar Geoff Pado

Display photo library picker with sample cells design

parent 8a4b71ff
......@@ -24,6 +24,12 @@
041EFF592255A2FB0058D8EE /* Aleo-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 041EFF572255A2EE0058D8EE /* Aleo-Regular.otf */; };
041EFF5B2255A39D0058D8EE /* Fonts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 041EFF5A2255A39D0058D8EE /* Fonts.swift */; };
041EFF5D2255A85F0058D8EE /* NavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 041EFF5C2255A85F0058D8EE /* NavigationController.swift */; };
041EFF6B225C36350058D8EE /* PhotoLibraryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 041EFF6A225C36350058D8EE /* PhotoLibraryViewController.swift */; };
041EFF6E225C38800058D8EE /* PhotoSelectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 041EFF6D225C38800058D8EE /* PhotoSelectionViewController.swift */; };
041EFF70225C3D830058D8EE /* PhotoLibraryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 041EFF6F225C3D830058D8EE /* PhotoLibraryView.swift */; };
041EFF72225C3DC00058D8EE /* PhotoLibraryDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 041EFF71225C3DC00058D8EE /* PhotoLibraryDataSource.swift */; };
041EFF74225C3DD20058D8EE /* PhotoLibraryViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 041EFF73225C3DD20058D8EE /* PhotoLibraryViewCell.swift */; };
041EFF76225C3DF10058D8EE /* PhotoLibraryViewLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 041EFF75225C3DF10058D8EE /* PhotoLibraryViewLayout.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
......@@ -58,6 +64,12 @@
041EFF572255A2EE0058D8EE /* Aleo-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Aleo-Regular.otf"; sourceTree = "<group>"; };
041EFF5A2255A39D0058D8EE /* Fonts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Fonts.swift; sourceTree = "<group>"; };
041EFF5C2255A85F0058D8EE /* NavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationController.swift; sourceTree = "<group>"; };
041EFF6A225C36350058D8EE /* PhotoLibraryViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoLibraryViewController.swift; sourceTree = "<group>"; };
041EFF6D225C38800058D8EE /* PhotoSelectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoSelectionViewController.swift; sourceTree = "<group>"; };
041EFF6F225C3D830058D8EE /* PhotoLibraryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoLibraryView.swift; sourceTree = "<group>"; };
041EFF71225C3DC00058D8EE /* PhotoLibraryDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoLibraryDataSource.swift; sourceTree = "<group>"; };
041EFF73225C3DD20058D8EE /* PhotoLibraryViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoLibraryViewCell.swift; sourceTree = "<group>"; };
041EFF75225C3DF10058D8EE /* PhotoLibraryViewLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoLibraryViewLayout.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
......@@ -99,8 +111,8 @@
041EFEF72251A9F30058D8EE /* Highlighter */ = {
isa = PBXGroup;
children = (
041EFF6C225C38600058D8EE /* Photo Selection */,
041EFF532255A0930058D8EE /* Style */,
041EFF4C225302B90058D8EE /* Intro View */,
041EFEF82251A9F30058D8EE /* AppDelegate.swift */,
041EFEFA2251A9F30058D8EE /* AppViewController.swift */,
041EFEFF2251A9F50058D8EE /* Assets.xcassets */,
......@@ -145,6 +157,28 @@
path = Style;
sourceTree = "<group>";
};
041EFF69225C36130058D8EE /* Photo Library */ = {
isa = PBXGroup;
children = (
041EFF6A225C36350058D8EE /* PhotoLibraryViewController.swift */,
041EFF6F225C3D830058D8EE /* PhotoLibraryView.swift */,
041EFF71225C3DC00058D8EE /* PhotoLibraryDataSource.swift */,
041EFF73225C3DD20058D8EE /* PhotoLibraryViewCell.swift */,
041EFF75225C3DF10058D8EE /* PhotoLibraryViewLayout.swift */,
);
path = "Photo Library";
sourceTree = "<group>";
};
041EFF6C225C38600058D8EE /* Photo Selection */ = {
isa = PBXGroup;
children = (
041EFF4C225302B90058D8EE /* Intro View */,
041EFF69225C36130058D8EE /* Photo Library */,
041EFF6D225C38800058D8EE /* PhotoSelectionViewController.swift */,
);
path = "Photo Selection";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
......@@ -250,15 +284,21 @@
files = (
041EFF5D2255A85F0058D8EE /* NavigationController.swift in Sources */,
041EFF492252FAF50058D8EE /* IntroViewController.swift in Sources */,
041EFF6B225C36350058D8EE /* PhotoLibraryViewController.swift in Sources */,
041EFF70225C3D830058D8EE /* PhotoLibraryView.swift in Sources */,
041EFF552255A0B00058D8EE /* Colors.swift in Sources */,
041EFF72225C3DC00058D8EE /* PhotoLibraryDataSource.swift in Sources */,
041EFEFB2251A9F30058D8EE /* AppViewController.swift in Sources */,
041EFF6E225C38800058D8EE /* PhotoSelectionViewController.swift in Sources */,
041EFF192251AAFE0058D8EE /* UIViewControllerExtensions.swift in Sources */,
041EFF52225303430058D8EE /* PromptButton.swift in Sources */,
041EFEF92251A9F30058D8EE /* AppDelegate.swift in Sources */,
041EFF76225C3DF10058D8EE /* PhotoLibraryViewLayout.swift in Sources */,
041EFF5B2255A39D0058D8EE /* Fonts.swift in Sources */,
041EFF50225303120058D8EE /* PromptLabel.swift in Sources */,
041EFF1B2251AB8D0058D8EE /* AppWindow.swift in Sources */,
041EFF4E225302CC0058D8EE /* IntroView.swift in Sources */,
041EFF74225C3DD20058D8EE /* PhotoLibraryViewCell.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......
......@@ -7,7 +7,7 @@ class AppViewController: UIViewController {
init() {
super.init(nibName: nil, bundle: nil)
let navigationController = NavigationController(rootViewController: IntroViewController())
let navigationController = NavigationController(rootViewController: PhotoSelectionViewController())
embed(navigationController)
}
......
......@@ -6,6 +6,6 @@
Copyright © 2019 Cocoatype, LLC. All rights reserved.
*/
"IntroViewController.navigationItemTitle" = "Welcome";
"IntroView.promptLabelText" = "Black Highlighter needs permission to edit your photos.";
"IntroView.promptButtonTitle" = "Grant Access";
"PhotoSelectionViewController.navigationItemTitle" = "Photos";
......@@ -7,7 +7,6 @@ import UIKit
class IntroViewController: UIViewController {
init() {
super.init(nibName: nil, bundle: nil)
navigationItem.title = IntroViewController.navigationItemTitle
}
override func loadView() {
......@@ -17,6 +16,12 @@ class IntroViewController: UIViewController {
@objc func requestPermission() {
PHPhotoLibrary.requestAuthorization { status in
print("got status: \(status)")
if status == .authorized {
DispatchQueue.main.async {
UIApplication.shared.sendAction(#selector(PhotoSelectionViewController.showPhotoLibrary), to: nil, from: self, for: nil)
}
}
}
print("permission requested")
......@@ -24,8 +29,6 @@ class IntroViewController: UIViewController {
// MARK: Boilerplate
private static let navigationItemTitle = NSLocalizedString("IntroViewController.navigationItemTitle", comment: "Navigation title for the intro view")
@available(*, unavailable)
required init(coder: NSCoder) {
let className = String(describing: type(of: self))
......
// Created by Geoff Pado on 4/8/19.
// Copyright © 2019 Cocoatype, LLC. All rights reserved.
import Photos
import UIKit
class PhotoLibraryDataSource: NSObject, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
let fetchOptions = PHFetchOptions()
let allPhotos = PHAsset.fetchAssets(with: fetchOptions)
return allPhotos.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
return collectionView.dequeueReusableCell(withReuseIdentifier: PhotoLibraryViewCell.identifier, for: indexPath)
}
}
// Created by Geoff Pado on 4/8/19.
// Copyright © 2019 Cocoatype, LLC. All rights reserved.
import UIKit
class PhotoLibraryView: UICollectionView {
init() {
let layout = PhotoLibraryViewLayout()
super.init(frame: .zero, collectionViewLayout: layout)
register(PhotoLibraryViewCell.self, forCellWithReuseIdentifier: PhotoLibraryViewCell.identifier)
backgroundColor = .primary
}
// MARK: Boilerplate
@available(*, unavailable)
required init(coder: NSCoder) {
let className = String(describing: type(of: self))
fatalError("\(className) does not implement init(coder:)")
}
}
// Created by Geoff Pado on 4/8/19.
// Copyright © 2019 Cocoatype, LLC. All rights reserved.
import UIKit
class PhotoLibraryViewCell: UICollectionViewCell {
static let identifier = "PhotoLibraryViewCell.identifier"
override init(frame: CGRect) {
super.init(frame: .zero)
backgroundColor = .red
}
// MARK: Boilerplate
@available(*, unavailable)
required init(coder: NSCoder) {
let className = String(describing: type(of: self))
fatalError("\(className) does not implement init(coder:)")
}
}
// Created by Geoff Pado on 4/8/19.
// Copyright © 2019 Cocoatype, LLC. All rights reserved.
import UIKit
class PhotoLibraryViewController: UIViewController {
init() {
super.init(nibName: nil, bundle: nil)
}
override func loadView() {
let libraryView = PhotoLibraryView()
libraryView.dataSource = dataSource
view = libraryView
}
// MARK: Boilerplate
private let dataSource = PhotoLibraryDataSource()
@available(*, unavailable)
required init(coder: NSCoder) {
let className = String(describing: type(of: self))
fatalError("\(className) does not implement init(coder:)")
}
}
// Created by Geoff Pado on 4/8/19.
// Copyright © 2019 Cocoatype, LLC. All rights reserved.
import UIKit
class PhotoLibraryViewLayout: UICollectionViewFlowLayout {
override init() {
super.init()
}
override func prepare() {
super.prepare()
itemSize = PhotoLibraryViewLayout.itemSize(for: collectionView?.traitCollection)
}
// MARK: Boilerplate
private static let smallCellSize = CGSize(width: 50.0, height: 50.0)
private static let largeCellSize = CGSize(width: 100.0, height: 100.0)
private static func itemSize(for traitCollection: UITraitCollection?) -> CGSize {
let horizontalSizeClass = traitCollection?.horizontalSizeClass ?? .unspecified
let verticalSizeClass = traitCollection?.verticalSizeClass ?? .unspecified
if (horizontalSizeClass, verticalSizeClass) == (.regular, .regular) {
return largeCellSize
} else { return smallCellSize }
}
@available(*, unavailable)
required init(coder: NSCoder) {
let className = String(describing: type(of: self))
fatalError("\(className) does not implement init(coder:)")
}
}
// Created by Geoff Pado on 4/8/19.
// Copyright © 2019 Cocoatype, LLC. All rights reserved.
import UIKit
class PhotoSelectionViewController: UIViewController {
init() {
super.init(nibName: nil, bundle: nil)
navigationItem.title = PhotoSelectionViewController.navigationItemTitle
embed(IntroViewController())
}
@objc func showPhotoLibrary() {
transition(to: PhotoLibraryViewController())
}
// MARK: Boilerplate
private static let navigationItemTitle = NSLocalizedString("PhotoSelectionViewController.navigationItemTitle", comment: "Navigation title for the photo selector")
@available(*, unavailable)
required init(coder: NSCoder) {
let className = String(describing: type(of: self))
fatalError("\(className) does not implement init(coder:)")
}
}
......@@ -23,7 +23,7 @@ extension UIViewController {
newChildView.heightAnchor.constraint(equalTo: view.heightAnchor),
newChildView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
newChildView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
])
}
func transition(to child: UIViewController, completion: ((Bool) -> Void)? = nil) {
......
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