深度页面转换UIView,Swift

时间:2015-11-19 08:07:14

标签: ios objective-c swift

如何创建深度页面像这样https://youtu.be/c2ccXwwmcnA转换动画(从上到下,从下到上)。我在谷歌搜索过,但我不知道如何在var yourVideo = document.getElementById('yourVideo'); video.src = 'your_video_' + value + '.ogg'; video.load(); yourVideo.addEventListener('loadeddata', function() { // Video is loaded and can be played }, false); 中实施。

示例输出像这样:

in depth effect

2 个答案:

答案 0 :(得分:11)

我按照教程Animated Transitions in Swift得到了这个效果:

in depth effect

如果您不想阅读整个教程,那么基本上您需要做的是:

1。创建TrasitionManager

//
//  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。实例化TransitionManager

中的ViewController
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

就是这样!

编辑:

要达到这个效果:

in depth effect 2

这是项目的一个git:https://github.com/alaphao/indepth

使用约束来调整大小:

  1. 创建两个视图,其父视图的宽度/高度相同

  2. 将两者与CenterX

  3. 对齐
  4. 设置距离底部的距离= 0并为约束创建出口

  5. 创建PanGestureRecognizer

  6. 根据平底锅translationInView.y

  7. 对前视图底部约束进行动画处理

答案 1 :(得分:3)

这是解决方案制作新的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 组件选择UICollectionView转到属性检查器并将布局从Flow更改为custom并将class属性设置为UltravisualLayout

这是项目link和本教程的link

希望这可能有助于好运..