Skip to content

Commit

Permalink
Merge branch 'release/1.1.4'
Browse files Browse the repository at this point in the history
  • Loading branch information
mluisbrown committed Aug 6, 2016
2 parents 13007d0 + 0326ba3 commit 85eeac5
Show file tree
Hide file tree
Showing 11 changed files with 186 additions and 33 deletions.
4 changes: 2 additions & 2 deletions Cartfile.resolved
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
github "robb/Cartography" "c73aa3bdcdf366a7648571e53075be8e8e10392b"
github "robb/Cartography" "114a314ce43ff68255c16a70e4c53824c9ecd539"
github "mluisbrown/DACircularProgress" "5b06959ce05b1332a09771915a1c2ea25c5554a9"
github "mluisbrown/RMStore" "9f5a865a1fb3d1a01259fd1d14a5b7cd6698117c"
github "mluisbrown/RMStore" "2da2208c64c734258ecb0fa263e3d25e9bce68b2"
6 changes: 5 additions & 1 deletion Memories.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
4C8594D31BB33E2F005CCFAC /* DACircularProgress.framework.dSYM in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4C8594D21BB33E2F005CCFAC /* DACircularProgress.framework.dSYM */; };
4C91432C1BA958CC001B30A9 /* notification.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 4C91432B1BA958CC001B30A9 /* notification.mp3 */; };
4C921FD21C1A038800F0411D /* PhotoViewPresentTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C921FD11C1A038800F0411D /* PhotoViewPresentTransition.swift */; };
4C92A9381D4C088E00B3FAAD /* StatusBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C92A9371D4C088E00B3FAAD /* StatusBarViewController.swift */; };
4C989BDF1BA7806E00D4C13F /* Dynamic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C989BDE1BA7806E00D4C13F /* Dynamic.swift */; };
4C989BE11BA780BB00D4C13F /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C989BE01BA780BB00D4C13F /* SettingsViewModel.swift */; };
4CAAF0751B827EAD00AE47C3 /* PullView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CAAF0741B827EAD00AE47C3 /* PullView.swift */; };
Expand Down Expand Up @@ -131,6 +132,7 @@
4C8594D21BB33E2F005CCFAC /* DACircularProgress.framework.dSYM */ = {isa = PBXFileReference; lastKnownFileType = wrapper.dsym; name = DACircularProgress.framework.dSYM; path = Carthage/Build/iOS/DACircularProgress.framework.dSYM; sourceTree = "<group>"; };
4C91432B1BA958CC001B30A9 /* notification.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = notification.mp3; sourceTree = "<group>"; };
4C921FD11C1A038800F0411D /* PhotoViewPresentTransition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoViewPresentTransition.swift; sourceTree = "<group>"; };
4C92A9371D4C088E00B3FAAD /* StatusBarViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusBarViewController.swift; sourceTree = "<group>"; };
4C989BDE1BA7806E00D4C13F /* Dynamic.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Dynamic.swift; sourceTree = "<group>"; };
4C989BE01BA780BB00D4C13F /* SettingsViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsViewModel.swift; sourceTree = "<group>"; };
4CAAF0741B827EAD00AE47C3 /* PullView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PullView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -209,6 +211,7 @@
4C989BDE1BA7806E00D4C13F /* Dynamic.swift */,
4C0410E51BC8787200BBB76C /* UIDevice.swift */,
4CABEE211CAAF08500A9F23A /* UITraitEnvironment.swift */,
4C92A9371D4C088E00B3FAAD /* StatusBarViewController.swift */,
);
path = Utilities;
sourceTree = "<group>";
Expand Down Expand Up @@ -265,8 +268,8 @@
4C641B901C3DB30C004B15D7 /* Transitions */ = {
isa = PBXGroup;
children = (
4C00A4F41C1B7ED30078A43F /* PhotoViewDismissTransition.swift */,
4C921FD11C1A038800F0411D /* PhotoViewPresentTransition.swift */,
4C00A4F41C1B7ED30078A43F /* PhotoViewDismissTransition.swift */,
);
path = Transitions;
sourceTree = "<group>";
Expand Down Expand Up @@ -552,6 +555,7 @@
4CEAA9101B33462600774FE8 /* GridViewCell.swift in Sources */,
4CBA89671BBC926100913336 /* UpgradeManager.swift in Sources */,
4CF4105C1C4BB732002FD49A /* DateUtils.swift in Sources */,
4C92A9381D4C088E00B3FAAD /* StatusBarViewController.swift in Sources */,
4CEAA90E1B3343F700774FE8 /* GridViewController.swift in Sources */,
4C00A4F51C1B7ED30078A43F /* PhotoViewDismissTransition.swift in Sources */,
4CE8BD971C03BBE500207BE1 /* DatePickerViewController.swift in Sources */,
Expand Down
5 changes: 5 additions & 0 deletions Memories/Grid View/GridViewCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,9 @@ class GridViewCell: UICollectionViewCell {
return imageView?.image
}
}

override func prepareForReuse() {
super.prepareForReuse()
imageView?.image = nil
}
}
34 changes: 33 additions & 1 deletion Memories/Grid View/GridViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,13 @@ extension UICollectionView {
}
}

class GridViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout, PHPhotoLibraryChangeObserver, UIPopoverPresentationControllerDelegate {
class GridViewController: UICollectionViewController,
UICollectionViewDelegateFlowLayout,
PHPhotoLibraryChangeObserver,
UIPopoverPresentationControllerDelegate,
StatusBarViewController,
PhotoViewControllerDelegate
{
let reuseIdentifier = "PhotoCell"
let headerIdentifier = "YearHeader"
// If the size is too large then PhotoKit doesn't return an optimal image size
Expand All @@ -43,6 +49,7 @@ class GridViewController: UICollectionViewController, UICollectionViewDelegateFl
var model : GridViewModel!

var titleView : UILabel!
var statusBarVisible = true

var imageManager : PHCachingImageManager!
var previousPreheatRect : CGRect = .zero
Expand Down Expand Up @@ -179,10 +186,22 @@ class GridViewController: UICollectionViewController, UICollectionViewDelegateFl
}, completion: nil)
}

override func prefersStatusBarHidden() -> Bool {
return !statusBarVisible || traitCollection.verticalSizeClass == .Compact
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}

// MARK: StatusBarViewController
func hideStatusBar(hide: Bool) {
statusBarVisible = !hide
UIView.animateWithDuration(0.25) {
self.setNeedsStatusBarAppearanceUpdate()
}
}

// MARK: - Notification handlers
func appDidBecomeActive() {
if let date = NotificationManager.launchDate() where self.photosAllowed {
Expand Down Expand Up @@ -216,6 +235,18 @@ class GridViewController: UICollectionViewController, UICollectionViewDelegateFl
}
}

// MARK: - PhotoViewContollerDelegate
func setSelected(index index: Int) {
collectionView?.selectItemAtIndexPath(model.indexPathForSelectedIndex(index), animated: false, scrollPosition: .CenteredVertically)
}

func imageView(atIndex index: Int) -> UIImageView? {
guard let cell = collectionView?.cellForItemAtIndexPath(model.indexPathForSelectedIndex(index)) as? GridViewCell else {
return nil
}

return cell.imageView
}

// MARK: - UIPopoverPresentationControllerDelegate
func popoverPresentationControllerShouldDismissPopover(popoverPresentationController: UIPopoverPresentationController) -> Bool {
Expand Down Expand Up @@ -243,6 +274,7 @@ class GridViewController: UICollectionViewController, UICollectionViewDelegateFl
override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
if let photoViewController = storyboard?.instantiateViewControllerWithIdentifier("photoViewController") as? PhotoViewController {
photoViewController.model = model.photoViewModelForIndexPath(indexPath)
photoViewController.delegate = self
if let cell = collectionView.cellForItemAtIndexPath(indexPath) as? GridViewCell, imageView = cell.imageView {
photoViewController.presentTransition = PhotoViewPresentTransition(sourceImageView: imageView)
photoViewController.transitioningDelegate = photoViewController
Expand Down
118 changes: 99 additions & 19 deletions Memories/Photo View/PhotoViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,26 @@
import UIKit
import Photos

class PhotoViewController: UIViewController, UIScrollViewDelegate, UIViewControllerTransitioningDelegate, PHPhotoLibraryChangeObserver, ZoomingPhotoViewDelegate {
protocol PhotoViewControllerDelegate {
func setSelected(index index: Int)
func imageView(atIndex index: Int) -> UIImageView?
}


class PhotoViewController: UIViewController,
UIScrollViewDelegate,
UIViewControllerTransitioningDelegate,
PHPhotoLibraryChangeObserver,
ZoomingPhotoViewDelegate
{
@IBOutlet var scrollView: UIScrollView!
@IBOutlet weak var shareButton: UIButton!
@IBOutlet weak var deleteButton: UIButton!
@IBOutlet weak var closeButton: UIButton!
@IBOutlet weak var heartButton: UIButton!
@IBOutlet weak var yearLabel: UILabel!

let PADDING : CGFloat = 10.0;
let PADDING = CGFloat(10)

let heartFullImg = UIImage(named: "heart-full")!.imageWithRenderingMode(.AlwaysTemplate)
let heartEmptyImg = UIImage(named: "heart-empty")!.imageWithRenderingMode(.AlwaysTemplate)
Expand All @@ -28,12 +39,23 @@ class PhotoViewController: UIViewController, UIScrollViewDelegate, UIViewControl
var model : PhotoViewModel!
var pageViews: [ZoomingPhotoView?] = []
let imageManager : PHCachingImageManager
var delegate: PhotoViewControllerDelegate?
// If the size is too large then PhotoKit doesn't return an optimal image size
// see rdar://25181601 (https://openradar.appspot.com/radar?id=6158824289337344)
let cacheSize = CGSize(width: 256, height: 256)

var hideStatusBar = false

struct PanState {
let imageView: UIImageView?
let destImageView: UIImageView?
let transform: CGAffineTransform
let center: CGPoint
let panHeight: CGFloat
}

var initialPanState = PanState(imageView: nil, destImageView: nil, transform: CGAffineTransformIdentity, center: .zero, panHeight: 0)

var presentTransition: PhotoViewPresentTransition?
var dismissTransition: PhotoViewDismissTransition?

Expand Down Expand Up @@ -64,12 +86,21 @@ class PhotoViewController: UIViewController, UIScrollViewDelegate, UIViewControl
initialPage = model.selectedIndex
imageManager.startCachingImagesForAssets(model.assets, targetSize: cacheSize, contentMode: .AspectFill, options: nil)
PHPhotoLibrary.sharedPhotoLibrary().registerChangeObserver(self);

let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(PhotoViewController.viewDidPan))
view.addGestureRecognizer(panRecognizer)
}

override func viewDidAppear(animated: Bool) {
hideStatusBar(true)
}

override func viewDidDisappear(animated: Bool) {
PHPhotoLibrary.sharedPhotoLibrary().unregisterChangeObserver(self)
self.cancelAllImageRequests()
self.purgeAllViews()
}

override func viewDidLayoutSubviews() {
setupViews()
}
Expand All @@ -79,7 +110,7 @@ class PhotoViewController: UIViewController, UIScrollViewDelegate, UIViewControl
initialPage = model.selectedIndex
initialOffsetSet = false
}

override func prefersStatusBarHidden() -> Bool {
return hideStatusBar || traitCollection.verticalSizeClass == .Compact
}
Expand All @@ -90,7 +121,7 @@ class PhotoViewController: UIViewController, UIScrollViewDelegate, UIViewControl
self.setNeedsStatusBarAppearanceUpdate()
}
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
Expand Down Expand Up @@ -138,21 +169,66 @@ class PhotoViewController: UIViewController, UIScrollViewDelegate, UIViewControl
}, completionHandler: nil)
}

func doClose() {
guard let delegate = delegate else {
return
}

delegate.setSelected(index: model.selectedIndex)
let imageView = delegate.imageView(atIndex: model.selectedIndex)!
let pageView = pageViews[model.selectedIndex]!

dismissTransition = PhotoViewDismissTransition(destImageView: imageView, sourceImageView: pageView.imageView)
presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
}

@IBAction func close(sender: UIButton) {
if let navController = presentingViewController as? UINavigationController,
gridViewController = navController.topViewController as? GridViewController {
cancelAllImageRequests()
PHPhotoLibrary.sharedPhotoLibrary().unregisterChangeObserver(self)

gridViewController.setSelectedIndex(model.selectedIndex)
if traitCollection.verticalSizeClass == .Regular {
hideStatusBar(false)
doClose()
}

func viewDidPan(gr: UIPanGestureRecognizer) {
switch gr.state {
case .Began:
let startPoint = gr.locationInView(gr.view)

let imageView = pageViews[model.selectedIndex]!.imageView!
initialPanState = PanState(imageView: imageView,
destImageView: delegate?.imageView(atIndex: model.selectedIndex),
transform: imageView.transform,
center: imageView.center,
panHeight: gr.view!.bounds.height - startPoint.y)
initialPanState.destImageView?.hidden = true
case .Changed:
let translation = gr.translationInView(gr.view)
let yPercent = translation.y / initialPanState.panHeight
let percent = yPercent <= 0 ? 0 : yPercent
let alpha = 1 - percent
let scale = (1 - percent / 2)

initialPanState.imageView?.center = CGPoint(x: initialPanState.center.x + translation.x, y: initialPanState.center.y + translation.y)
initialPanState.imageView?.transform = CGAffineTransformScale(initialPanState.transform, scale, scale)

view.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(alpha)
if !controlsHidden { setControls(alpha: alpha) }

case .Ended, .Cancelled:
let velocity = gr.velocityInView(gr.view)
if velocity.y < 0 || gr.state == .Cancelled {
UIView.animateWithDuration(0.25, animations: {
self.initialPanState.imageView?.center = self.initialPanState.center
self.initialPanState.imageView?.transform = self.initialPanState.transform
self.view.backgroundColor = UIColor.blackColor()
if !self.controlsHidden { self.setControls(alpha: 1) }
}) { finished in
self.initialPanState.destImageView?.hidden = false
}
}
let imageView = gridViewController.imageViewForIndex(model.selectedIndex)
let pageView = pageViews[model.selectedIndex]
dismissTransition = PhotoViewDismissTransition(destImageView: imageView!, sourceImageView: pageView!.imageView)

navController.dismissViewControllerAnimated(true) { self.purgeAllViews() }
else {
doClose()
}

default:
break
}
}

Expand Down Expand Up @@ -433,8 +509,12 @@ class PhotoViewController: UIViewController, UIScrollViewDelegate, UIViewControl
return
}

setControls(alpha: hide ? 0 : 1)
}

func setControls(alpha alpha: CGFloat) {
[shareButton, deleteButton, closeButton, heartButton, yearLabel].forEach {
$0.alpha = hide ? 0 : 1
$0.alpha = alpha
}
}

Expand Down
2 changes: 1 addition & 1 deletion Memories/Photo View/ZoomingPhotoView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ class ZoomingPhotoView: UIScrollView, UIScrollViewDelegate {

// only allow scrolling if the image has been zoomed
// larger than the window
scrollEnabled = zoomScale >= minZoom
scrollEnabled = zoomScale > minZoom

adjustImageConstraintsForZoomScale(zoomScale)
}
Expand Down
4 changes: 2 additions & 2 deletions Memories/Supporting Files/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.1.3</string>
<string>1.1.4</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
Expand All @@ -32,7 +32,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>18</string>
<string>19</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>itms-apps</string>
Expand Down
11 changes: 6 additions & 5 deletions Memories/Transitions/PhotoViewDismissTransition.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
//

import UIKit
import AVFoundation

class PhotoViewDismissTransition: NSObject, UIViewControllerAnimatedTransitioning {

Expand All @@ -28,16 +27,17 @@ class PhotoViewDismissTransition: NSObject, UIViewControllerAnimatedTransitionin
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
guard let container = transitionContext.containerView(),
fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey),
toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey),
fromView = transitionContext.viewForKey(UITransitionContextFromViewKey) else {
transitionContext.completeTransition(false)
return
}

let transitionView = UIView(frame: transitionContext.initialFrameForViewController(fromViewController))
transitionView.backgroundColor = UIColor.blackColor()
transitionView.backgroundColor = fromView.backgroundColor
container.insertSubview(transitionView, belowSubview: fromView)

let startImageFrame = CGRectIntegral(transitionView.convertRect(self.sourceImageView.bounds, fromView: self.sourceImageView))
let startImageFrame = self.sourceImageView.frame
let imageView = UIImageView(frame: startImageFrame)
imageView.image = destImageView.image
imageView.contentMode = container.thumbnailContentMode
Expand All @@ -48,9 +48,10 @@ class PhotoViewDismissTransition: NSObject, UIViewControllerAnimatedTransitionin
self.destImageView.hidden = true
self.sourceImageView.hidden = true

let newImageFrame = CGRectIntegral(transitionView.convertRect(self.destImageView.bounds, fromView: self.destImageView))

UIView.animateKeyframesWithDuration(duration, delay: 0, options: .CalculationModeLinear, animations: {
toViewController.statusBarContoller()?.hideStatusBar(false)
let newImageFrame = CGRectIntegral(transitionView.convertRect(self.destImageView.bounds, fromView: self.destImageView))

UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration: 0.25) {
fromView.alpha = 0.0
}
Expand Down
Loading

0 comments on commit 85eeac5

Please sign in to comment.