I'm trying to achieve literally this effect shown on Facebook's photo collectionview:
Video: http://d.pr/v/YCDB
I'm trying to have the following:
Animating to and from the indexpath of the cell Pan up and down to fade the view out and dismiss it Pretty much what's in the video.
Here's what I've done so far and it's a little janky on the animations and I can't figure out the to and from the index path part at all.
My CollectionView:
import UIKit
class Feed: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
var collectionView: UICollectionView?
var myArray = ["cool", "neat", "fun", "cool", "neat", "fun", "cool", "neat", "fun", "cool", "neat", "fun", "cool", "neat", "fun", "cool", "neat", "fun", "cool", "neat", "fun", "cool", "neat", "fun"]
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.yellowColor()
self.title = "Feed"
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
layout.itemSize = CGSize(width: 100, height: 100)
collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
collectionView!.dataSource = self
collectionView!.delegate = self
collectionView!.registerClass(Cell.self, forCellWithReuseIdentifier: "Cell")
collectionView!.backgroundColor = UIColor.whiteColor()
self.view.addSubview(collectionView!)
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return myArray.count
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as Cell
cell.textLabel.text = myArray[indexPath.row]
return cell
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as Cell
cell.textLabel.text = myArray[indexPath.row]
let vc:Detail = Detail()
let navController:CustomNavigationController = CustomNavigationController(rootViewController: vc)
println(cell.textLabel.text)
vc.myLabel.text = cell.textLabel.text
presentViewController(navController, animated: true, completion: nil)
}
}
My Transition
import UIKit
@objc protocol CustomNavigationControllerDelegate {
func pushToNextScene()
}
class CustomNavigationController: UINavigationController, UIViewControllerTransitioningDelegate, UINavigationControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
transitioningDelegate = self // for presenting the original navigation controller
delegate = self // for navigation controller custom transitions
let top = UIPanGestureRecognizer(target: self, action: "handleSwipeFromTop:")
self.view.addGestureRecognizer(top);
}
var interactionController: UIPercentDrivenInteractiveTransition?
func handleSwipeFromTop(gesture: UIPanGestureRecognizer) {
let percent = gesture.translationInView(gesture.view!).y / gesture.view!.bounds.size.height
if gesture.state == .Began {
interactionController = UIPercentDrivenInteractiveTransition()
if viewControllers.count > 1 {
popViewControllerAnimated(true)
} else {
dismissViewControllerAnimated(true, completion: nil)
}
} else if gesture.state == .Changed {
interactionController?.updateInteractiveTransition(percent)
} else if gesture.state == .Ended {
if percent > 0.2 {
interactionController?.finishInteractiveTransition()
} else {
interactionController?.cancelInteractiveTransition()
}
interactionController = nil
}
}
// MARK: - UIViewControllerTransitioningDelegate
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return ForwardAnimator()
}
func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return BackAnimator()
}
func interactionControllerForPresentation(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
return interactionController
}
func interactionControllerForDismissal(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
return interactionController
}
// MARK: - UINavigationControllerDelegate
func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
if operation == .Push {
return ForwardAnimator()
} else if operation == .Pop {
return BackAnimator()
}
return nil
}
func navigationController(navigationController: UINavigationController, interactionControllerForAnimationController animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
return interactionController
}
}
class ForwardAnimator : NSObject, UIViewControllerAnimatedTransitioning {
func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval {
return 0.3
}
func animateTransition(context: UIViewControllerContextTransitioning) {
let toView = context.viewControllerForKey(UITransitionContextToViewControllerKey)?.view
let fromView = context.viewControllerForKey(UITransitionContextFromViewControllerKey)?.view
context.containerView().addSubview(toView!)
toView?.alpha = 0.0
UIView.animateWithDuration(transitionDuration(context), animations: {
toView?.alpha = 1.0
return
}, completion: { finished in
context.completeTransition(!context.transitionWasCancelled())
})
}
}
class BackAnimator : NSObject, UIViewControllerAnimatedTransitioning {
func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval {
return 0.2
}
func animateTransition(context: UIViewControllerContextTransitioning) {
let toView = context.viewControllerForKey(UITransitionContextToViewControllerKey)?.view
let fromView = context.viewControllerForKey(UITransitionContextFromViewControllerKey)?.view
context.containerView().insertSubview(toView!, belowSubview: fromView!)
UIView.animateWithDuration(transitionDuration(context), animations: {
fromView?.alpha = 0.0
return
}, completion: { finished in
context.completeTransition(!context.transitionWasCancelled())
})
}
}
And if you want it/ease to recreate:
My Cell
import UIKit
class Cell: UICollectionViewCell {
let textLabel: UILabel!
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.greenColor()
let textFrame = CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height)
textLabel = UILabel(frame: textFrame)
textLabel.font = UIFont.systemFontOfSize(UIFont.smallSystemFontSize())
textLabel.textAlignment = .Center
contentView.addSubview(textLabel)
}
}
My Detail View
import UIKit
class Detail: UIViewController, CustomNavigationControllerDelegate {
var myLabel : UILabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor(white: 0, alpha: 0.7)
let myBtn: UIButton = UIButton()
myBtn.frame = CGRectMake(100, 100, 100, 100)
myBtn.backgroundColor = UIColor.greenColor()
myBtn.addTarget(self, action: "goNext", forControlEvents: UIControlEvents.TouchUpInside)
self.view.addSubview(myBtn)
myLabel.textColor = UIColor.whiteColor()
myLabel.frame = self.view.bounds
self.view.addSubview(myLabel)
}
func pushToNextScene() {
self.dismissViewControllerAnimated(true, completion: nil)
}
func goNext () {
println("button")
self.dismissViewControllerAnimated(true, completion: nil)
}
}
Aucun commentaire:
Enregistrer un commentaire