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

Display photos in photo picker

parent c09a5ea0
......@@ -30,6 +30,8 @@
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 */; };
04D68BC5225EE2C000D09BBD /* GeometryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04D68BC4225EE2C000D09BBD /* GeometryExtensions.swift */; };
04D68BC7225EE2FD00D09BBD /* PhotoLibraryViewCellImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04D68BC6225EE2FD00D09BBD /* PhotoLibraryViewCellImageView.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
......@@ -70,6 +72,8 @@
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>"; };
04D68BC4225EE2C000D09BBD /* GeometryExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeometryExtensions.swift; sourceTree = "<group>"; };
04D68BC6225EE2FD00D09BBD /* PhotoLibraryViewCellImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoLibraryViewCellImageView.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
......@@ -118,7 +122,7 @@
041EFEFF2251A9F50058D8EE /* Assets.xcassets */,
041EFF012251A9F50058D8EE /* LaunchScreen.storyboard */,
041EFF042251A9F50058D8EE /* Info.plist */,
041EFF182251AAFE0058D8EE /* UIViewControllerExtensions.swift */,
04D68BC3225EE2A500D09BBD /* Extensions */,
041EFF1A2251AB8D0058D8EE /* AppWindow.swift */,
041EFF4A225300030058D8EE /* Localizable.strings */,
041EFF5C2255A85F0058D8EE /* NavigationController.swift */,
......@@ -164,6 +168,7 @@
041EFF6F225C3D830058D8EE /* PhotoLibraryView.swift */,
041EFF71225C3DC00058D8EE /* PhotoLibraryDataSource.swift */,
041EFF73225C3DD20058D8EE /* PhotoLibraryViewCell.swift */,
04D68BC6225EE2FD00D09BBD /* PhotoLibraryViewCellImageView.swift */,
041EFF75225C3DF10058D8EE /* PhotoLibraryViewLayout.swift */,
);
path = "Photo Library";
......@@ -179,6 +184,15 @@
path = "Photo Selection";
sourceTree = "<group>";
};
04D68BC3225EE2A500D09BBD /* Extensions */ = {
isa = PBXGroup;
children = (
041EFF182251AAFE0058D8EE /* UIViewControllerExtensions.swift */,
04D68BC4225EE2C000D09BBD /* GeometryExtensions.swift */,
);
path = Extensions;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
......@@ -294,11 +308,13 @@
041EFF52225303430058D8EE /* PromptButton.swift in Sources */,
041EFEF92251A9F30058D8EE /* AppDelegate.swift in Sources */,
041EFF76225C3DF10058D8EE /* PhotoLibraryViewLayout.swift in Sources */,
04D68BC7225EE2FD00D09BBD /* PhotoLibraryViewCellImageView.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 */,
04D68BC5225EE2C000D09BBD /* GeometryExtensions.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......
// Created by Geoff Pado on 4/10/19.
// Copyright © 2019 Cocoatype, LLC. All rights reserved.
import UIKit
extension CGSize {
static func * (size: CGSize, multiplier: CGFloat) -> CGSize {
return CGSize(width: size.width * multiplier, height: size.height * multiplier)
}
}
......@@ -6,12 +6,24 @@ 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)
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: PhotoLibraryViewCell.identifier, for: indexPath)
guard let photoCell = cell as? PhotoLibraryViewCell else {
fatalError("Got incorrect type of cell for photo picker: \(String(describing: type(of: cell)))")
}
photoCell.asset = allPhotos[indexPath.item]
return cell
}
// MARK: Photos
lazy var allPhotos: PHFetchResult<PHAsset> = {
let fetchOptions = PHFetchOptions()
return PHAsset.fetchAssets(with: fetchOptions)
}()
}
// Created by Geoff Pado on 4/8/19.
// Copyright © 2019 Cocoatype, LLC. All rights reserved.
import Photos
import UIKit
class PhotoLibraryViewCell: UICollectionViewCell {
static let identifier = "PhotoLibraryViewCell.identifier"
var asset: PHAsset? {
didSet {
guard let asset = asset else {
assetRequestID = nil
imageView.image = nil
return
}
let targetSize = bounds.size * UIScreen.main.scale
assetRequestID = imageManager.requestImage(for: asset, targetSize: targetSize, contentMode: .aspectFill, options: nil) { [weak self] image, info in
guard let image = image,
let requestID = (info?[PHImageResultRequestIDKey] as? NSNumber)?.int32Value,
self?.assetRequestID == requestID
else { return }
self?.imageView.image = image
}
}
}
override init(frame: CGRect) {
imageView = PhotoLibraryViewCellImageView()
super.init(frame: .zero)
contentView.addSubview(imageView)
NSLayoutConstraint.activate([
imageView.widthAnchor.constraint(equalTo: contentView.widthAnchor),
imageView.heightAnchor.constraint(equalTo: contentView.heightAnchor),
imageView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
imageView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor)
])
backgroundColor = .red
}
override func prepareForReuse() {
super.prepareForReuse()
asset = nil
}
// MARK: Boilerplate
private let imageManager = PHImageManager.default()
private var imageView: UIImageView
private var assetRequestID: PHImageRequestID? {
didSet {
guard let oldValue = oldValue else { return }
imageManager.cancelImageRequest(oldValue)
}
}
@available(*, unavailable)
required init(coder: NSCoder) {
let className = String(describing: type(of: self))
......
// Created by Geoff Pado on 4/10/19.
// Copyright © 2019 Cocoatype, LLC. All rights reserved.
import UIKit
class PhotoLibraryViewCellImageView: UIImageView {
init() {
super.init(frame: .zero)
clipsToBounds = true
contentMode = .scaleAspectFill
translatesAutoresizingMaskIntoConstraints = false
}
// MARK: Boilerplate
@available(*, unavailable)
required init(coder: NSCoder) {
let className = String(describing: type(of: self))
fatalError("\(className) does not implement init(coder:)")
}
}
......@@ -11,13 +11,14 @@ class PhotoLibraryViewLayout: UICollectionViewFlowLayout {
override func prepare() {
super.prepare()
minimumInteritemSpacing = 1.0
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 let smallCellSize = CGSize(width: 74.0, height: 74.0)
private static let largeCellSize = CGSize(width: 190.0, height: 190.0)
private static func itemSize(for traitCollection: UITraitCollection?) -> CGSize {
let horizontalSizeClass = traitCollection?.horizontalSizeClass ?? .unspecified
......
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