深入页面转换UIView,Swift

如何创build深度页面像这样https://youtu.be/c2ccXwwmcnA转换animation(从上到下,从下到上)。 我在谷歌search,但我不知道如何在iOS实现。

示例输出像这样:

深入的影响

我跟着教程在Swift中的animation过渡 ,我得到了这样的效果:

深入的影响

如果你不想阅读整个教程,这里基本上是你必须做的:

1.创buildTrasitionManager

 // // TransitionManager.swift // Aleph Retamal // // Created by Aleph Retamal on 4/19/15. // Copyright (c) 2015 Aleph Retamal. All rights reserved. // import UIKit class TransitionManager: NSObject, UIViewControllerAnimatedTransitioning, UIViewControllerTransitioningDelegate { private var presenting:Bool = true var leftSide:Bool = true // MARK: UIViewControllerAnimatedTransitioning protocol methods // animate a change from one viewcontroller to another func animateTransition(transitionContext: UIViewControllerContextTransitioning) { // get reference to our fromView, toView and the container view that we should perform the transition in let container = transitionContext.containerView() let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)! let toView = transitionContext.viewForKey(UITransitionContextToViewKey)! let offScreenRight = CGAffineTransformConcat(CGAffineTransformMakeTranslation(container!.frame.width, 0), CGAffineTransformMakeScale(0.1, 0.1)) let offScreenLeft = CGAffineTransformMakeTranslation(-container!.frame.width, 0) // start the toView to the right of the screen if !leftSide { if self.presenting { toView.transform = offScreenRight } else { toView.transform = offScreenLeft } } else { if self.presenting { toView.transform = offScreenLeft } else { toView.transform = offScreenRight } } // add the both views to our view controller container!.addSubview(toView) container!.addSubview(fromView) // get the duration of the animation // DON'T just type '0.5s' -- the reason why won't make sense until the next post // but for now it's important to just follow this approach let duration = self.transitionDuration(transitionContext) // perform the animation! // for this example, just slid both fromView and toView to the left at the same time // meaning fromView is pushed off the screen and toView slides into view // we also use the block animation usingSpringWithDamping for a little bounce UIView.animateWithDuration(duration, animations: { () -> Void in if !self.leftSide { if self.presenting { fromView.transform = offScreenLeft } else { container!.sendSubviewToBack(fromView) fromView.transform = offScreenRight } } else { if self.presenting { fromView.transform = offScreenRight container!.sendSubviewToBack(fromView) } else { fromView.transform = offScreenLeft } } toView.transform = CGAffineTransformIdentity }) { (finished) -> Void in // tell our transitionContext object that we've finished animating transitionContext.completeTransition(true) } } // return how many seconds the transiton animation will take func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval { return 1.0 } // MARK: UIViewControllerTransitioningDelegate protocol methods // return the animataor when presenting a viewcontroller // remmeber that an animator (or animation controller) is any object that aheres to the UIViewControllerAnimatedTransitioning protocol func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? { self.presenting = true return self } // return the animator used when dismissing from a viewcontroller func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { self.presenting = false return self } } 

这是您设置视图如何转换的地方

 let offScreenRight = CGAffineTransformConcat(CGAffineTransformMakeTranslation(container!.frame.width, 0), CGAffineTransformMakeScale(0.1, 0.1)) let offScreenLeft = CGAffineTransformMakeTranslation(-container!.frame.width, 0) 

在这种情况下,一个视图将翻译 + 规模,而另一个将只翻译

2.在ViewController实例化TransitionManager

 let transitionManager = TransitionManager() 

3.设置转换委托

 override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { transitionManager.leftSide = false let toViewController = segue.destinationViewController toViewController.transitioningDelegate = self.transitionManager } 

如果您希望视图来自右侧,则leftSide = false

 transitionManager.leftSide = false 

而已!

编辑:

为了达到这个效果:

深度效果2

这是一个与该项目的Git: https : //github.com/alaphao/indepth

使用约束来resize:

  1. 使用其父视图的相同宽度/高度创build2个视图

  2. CenterXalignment

  3. 设置距底部= 0的距离并为约束创build出口

  4. 创build一个PanGestureRecognizer

  5. 将前视图底部的约束相应地设置为平移translationInView.y

这里是解决scheme使新的swift文件和复制此代码

 import UIKit class UltravisualLayout: UICollectionViewLayout { private var contentWidth:CGFloat! private var contentHeight:CGFloat! private var yOffset:CGFloat = 0 var maxAlpha:CGFloat = 1 var minAlpha:CGFloat = 0 //DEFAULT VALUES //var widthOffset:CGFloat = 35 // var heightOffset:CGFloat = 35 var widthOffset:CGFloat = 100 var heightOffset:CGFloat = 100 private var cache = [UICollectionViewLayoutAttributes]() private var itemWidth:CGFloat{ return (collectionView?.bounds.width)! } private var itemHeight:CGFloat{ return (collectionView?.bounds.height)! } private var collectionViewHeight:CGFloat{ return (collectionView?.bounds.height)! } private var numberOfItems:Int{ return (collectionView?.numberOfItemsInSection(0))! } private var dragOffset:CGFloat{ return (collectionView?.bounds.height)! } private var currentItemIndex:Int{ return max(0, Int(collectionView!.contentOffset.y / collectionViewHeight)) } var nextItemBecomeCurrentPercentage:CGFloat{ return (collectionView!.contentOffset.y / (collectionViewHeight)) - CGFloat(currentItemIndex) } override func prepareLayout() { cache.removeAll(keepCapacity: false) yOffset = 0 for item in 0 ..< numberOfItems{ let indexPath = NSIndexPath(forItem: item, inSection: 0) let attribute = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath) attribute.zIndex = -indexPath.row if (indexPath.item == currentItemIndex+1) && (indexPath.item < numberOfItems){ attribute.alpha = minAlpha + max((maxAlpha-minAlpha) * nextItemBecomeCurrentPercentage, 0) let width = itemWidth - widthOffset + (widthOffset * nextItemBecomeCurrentPercentage) let height = itemHeight - heightOffset + (heightOffset * nextItemBecomeCurrentPercentage) let deltaWidth = width/itemWidth let deltaHeight = height/itemHeight attribute.frame = CGRectMake(0, yOffset, itemWidth, itemHeight) attribute.transform = CGAffineTransformMakeScale(deltaWidth, deltaHeight) attribute.center.y = (collectionView?.center.y)! + (collectionView?.contentOffset.y)! attribute.center.x = (collectionView?.center.x)! + (collectionView?.contentOffset.x)! yOffset += collectionViewHeight }else{ attribute.frame = CGRectMake(0, yOffset, itemWidth, itemHeight) attribute.center.y = (collectionView?.center.y)! + yOffset attribute.center.x = (collectionView?.center.x)! yOffset += collectionViewHeight } cache.append(attribute) } } //Return the size of ContentView override func collectionViewContentSize() -> CGSize { contentWidth = (collectionView?.bounds.width)! contentHeight = CGFloat(numberOfItems) * (collectionView?.bounds.height)! return CGSizeMake(contentWidth, contentHeight) } //Return Attributes whose frame lies in the Visible Rect override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? { var layoutAttributes = [UICollectionViewLayoutAttributes]() for attribute in cache{ if CGRectIntersectsRect(attribute.frame, rect){ layoutAttributes.append(attribute) } } return layoutAttributes } override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool { return true } override func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint { let itemIndex = round(proposedContentOffset.y / (dragOffset)) let yOffset = itemIndex * (collectionView?.bounds.height)! return CGPoint(x: 0, y: yOffset) } override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? { // Logic that calculates the UICollectionViewLayoutAttributes of the item // and returns the UICollectionViewLayoutAttributes return UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath) } } 

在Main.storyboard文件中使用UICollectionView或UICollectionViewController组件selectUICollectionView转到属性检查器并将布局从Flow更改为自定义并将类属性设置为UltravisualLayout

这里是项目链接和这个教程的链接

希望这可能会帮助好运..