这是我的自定义Segue的代码
class FlipFromrightSegue: UIStoryboardSegue {
override func perform() {
    let source:UIViewController = self.sourceViewController as UIViewController
    let destination:UIViewController = self.destinationViewController as UIViewController

    UIView.transitionWithView(source.view,duration: 1.0,options: .CurveEaseInOut | .TransitionFlipFromright,animations: { () -> Void in
        source.view.addSubview(destination.view)
    }) { (finished) -> Void in
        destination.view.removeFromSuperview()
        source.presentViewController(destination,animated: false,completion: nil)
    }
}
}

我认为这有效但实际上只有在已经执行segue时视图才会改变.当“翻转”位于中间时,我该怎么做才能使视图发生变化?

提前致谢.

从iOS 7开始,我们通常不使用自定义segue为转换设置动画.我们要么使用标准模态演示,指定modalTransitionStyle(即我们可以为模态过渡选择的几个动画的固定列表),要么实现自定义动画过渡.这两个描述如下:

>如果您只是呈现另一个视图控制器的视图,则将动画更改为翻转的简单解决方案是在目标视图控制器中设置modalTransitionStyle.您可以在segue的属性下完全在Interface Builder中完成此操作.

如果您想以编程方式执行此操作,则可以在目标控制器中在Swift 3中执行以下操作:

override func viewDidLoad() {
    super.viewDidLoad()

    modalTransitionStyle = .flipHorizontal   // use `.FlipHorizontal` in Swift 2
}

然后,当您调用show / showViewController或present / presentViewController时,您的演示文稿将以水平翻转方式执行.并且,当您关闭视图控制器时,动画会自动反转.
>如果您需要更多控制,在iOS 7及更高版本中,您将使用自定义动画过渡,您可以在其中指定.custom的modalPresentationStyle.例如,在Swift 3中:

class SecondViewController: UIViewController {

    let customTransitionDelegate = TransitioningDelegate()

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        modalPresentationStyle = .custom   // use `.Custom` in Swift 2
        transitioningDelegate = customTransitionDelegate
    }

    ...
}

这指定了将实例化动画控制器的UIViewControllerTransitioningDelegate.例如,在Swift 3中:

class TransitioningDelegate: NSObject,UIViewControllerTransitioningDelegate {
    func animationController(forPresented presented: UIViewController,presenting: UIViewController,source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return AnimationController(transitionType: .presenting)
    }

    func animationController(fordismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return AnimationController(transitionType: .dismissing)
    }
}

动画控制器只是做.transitionFlipFromright是一个演示文稿,或者.transitionFlipFromLeft如果在Swift 3中被解雇:

class AnimationController: NSObject,UIViewControllerAnimatedTransitioning {

    enum TransitionType {
        case presenting
        case dismissing
    }

    var animationTransitionoptions: UIViewAnimationoptions

    init(transitionType: TransitionType) {
        switch transitionType {
        case .presenting:
            animationTransitionoptions = .transitionFlipFromright
        case .dismissing:
            animationTransitionoptions = .transitionFlipFromLeft
        }

        super.init()
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        //let inView   = transitionContext.containerView
        let toView   = transitionContext.viewController(forKey: .to)?.view
        let fromView = transitionContext.viewController(forKey: .from)?.view

        UIView.transition(from: fromView!,to: toView!,duration: transitionDuration(using: transitionContext),options: animationTransitionoptions.union(.curveEaseInOut)) { finished in
            transitionContext.completeTransition(true)
        }
    }

    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 1.0
    }
}

有关iOS 7中引入的自定义过渡的更多信息,请参阅WWDC 2013视频Custom Transitions Using View Controllers.
>如果应该承认上面的AnimationController实际上是一个过度简化,因为我们正在使用transform(from:to:…).这会导致动画无法取消(如果您正在使用交互式过渡).它也删除了“从”视图本身,从iOS 8开始,现在它实际上是演示控制器的工作.

所以,你真的想用UIView.animate API做翻转动画.我很抱歉,因为以下内容涉及在关键帧动画中使用一些不直观的CATransform3D,但它会产生一个翻转动画,然后可以进行可取消的交互式转换.

所以,在Swift 3中:

class AnimationController: NSObject,UIViewControllerAnimatedTransitioning {

    enum TransitionType {
        case presenting
        case dismissing
    }

    let transitionType: TransitionType

    init(transitionType: TransitionType) {
        self.transitionType = transitionType

        super.init()
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        let inView   = transitionContext.containerView
        let toView   = transitionContext.view(forKey: .to)!
        let fromView = transitionContext.view(forKey: .from)!

        var frame = inView.bounds

        func flipTransform(angle: CGFloat,offset: CGFloat = 0) -> CATransform3D {
            var transform = CATransform3DMakeTranslation(offset,0)
            transform.m34 = -1.0 / 1600
            transform = CATransform3DRotate(transform,angle,1,0)
            return transform
        }

        toView.frame = inView.bounds
        toView.alpha = 0

        let transformFromStart:  CATransform3D
        let transformFromEnd:    CATransform3D
        let transformFromMiddle: CATransform3D
        let transformToStart:    CATransform3D
        let transformToMiddle:   CATransform3D
        let transformToEnd:      CATransform3D

        switch transitionType {
        case .presenting:
            transformFromStart  = flipTransform(angle: 0,offset: inView.bounds.size.width / 2)
            transformFromEnd    = flipTransform(angle: -.pi,offset: inView.bounds.size.width / 2)
            transformFromMiddle = flipTransform(angle: -.pi / 2)
            transformToStart    = flipTransform(angle: .pi,offset: -inView.bounds.size.width / 2)
            transformToMiddle   = flipTransform(angle: .pi / 2)
            transformToEnd      = flipTransform(angle: 0,offset: -inView.bounds.size.width / 2)

            toView.layer.anchorPoint = CGPoint(x: 0,y: 0.5)
            fromView.layer.anchorPoint = CGPoint(x: 1,y: 0.5)

        case .dismissing:
            transformFromStart  = flipTransform(angle: 0,offset: -inView.bounds.size.width / 2)
            transformFromEnd    = flipTransform(angle: .pi,offset: -inView.bounds.size.width / 2)
            transformFromMiddle = flipTransform(angle: .pi / 2)
            transformToStart    = flipTransform(angle: -.pi,offset: inView.bounds.size.width / 2)
            transformToMiddle   = flipTransform(angle: -.pi / 2)
            transformToEnd      = flipTransform(angle: 0,offset: inView.bounds.size.width / 2)

            toView.layer.anchorPoint = CGPoint(x: 1,y: 0.5)
            fromView.layer.anchorPoint = CGPoint(x: 0,y: 0.5)
        }

        toView.layer.transform = transformToStart
        fromView.layer.transform = transformFromStart
        inView.addSubview(toView)

        UIView.animateKeyframes(withDuration: self.transitionDuration(using: transitionContext),delay: 0,options: [],animations: {
            UIView.addKeyframe(withRelativeStartTime: 0,relativeDuration: 0.0) {
                toView.alpha = 0
                fromView.alpha = 1
            }
            UIView.addKeyframe(withRelativeStartTime: 0,relativeDuration: 0.5) {
                toView.layer.transform = transformToMiddle
                fromView.layer.transform = transformFromMiddle
            }
            UIView.addKeyframe(withRelativeStartTime: 0.5,relativeDuration: 0.0) {
                toView.alpha = 1
                fromView.alpha = 0
            }
            UIView.addKeyframe(withRelativeStartTime: 0.5,relativeDuration: 0.5) {
                toView.layer.transform = transformToEnd
                fromView.layer.transform = transformFromEnd
            }
        },completion: { finished in
            toView.layer.transform = CATransform3DIdentity
            fromView.layer.transform = CATransform3DIdentity
            toView.layer.anchorPoint = CGPoint(x: 0.5,y: 0.5)
            fromView.layer.anchorPoint = CGPoint(x: 0.5,y: 0.5)

            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
        })
    }

    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 1.0
    }
}

>仅供参考,iOS 8通过演示控制器扩展了自定义转换模型.有关更多信息,请参阅WWDC 2014视频A Look Inside Presentation Controllers.

无论如何,如果在转换结束时,“from”视图不再可见,您将指示您的演示控制器将其从视图层次结构中删除,例如:

class PresentationController: UIPresentationController {
    override var shouldRemovePresentersView: Bool { return true }
}

显然,你必须通知你的TransitioningDelegate这个演示控制器:

class TransitioningDelegate: NSObject,UIViewControllerTransitioningDelegate {

    ...

    func presentationController(forPresented presented: UIViewController,presenting: UIViewController?,source: UIViewController) -> UIPresentationController? {
        return PresentationController(presentedViewController: presented,presenting: presenting)
    }            
}

此答案已针对Swift 3进行了更新.如果您想查看Swift 2实现,请参阅previous revision of this answer.

Swift中的自定义Flip Segue的更多相关文章

  1. html5录音功能实战示例

    这篇文章主要介绍了html5录音功能实战示例的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  2. SnapKit更新约束-Swift3.0

    导入SnapKit修改约束建立约束

  3. 你需要的大概不是 enumerated

    enumerated()很容易被误解。然而,它的startIndex很明显是2,而不是0,但当我们调用enumerated()和first的时候,它会返回一个元组,包含了一个offset,值为0,以及它的第一个元素“c”。而且实际上你获取到的是一个offset,而不是index,使用enumerated()也会有别的问题。很多时候你也许想用enumerated(),但有别的更好的抽象可以使用。下面是一个例子:因为这里的offset是作为一个数字去使用,enumerated()就可以正常运作。

  4. Swift*UINavigationBar动态颜色/透明度/隐藏

    所以,虽然很想省功夫,直接在navigationBar的基础上去做更改,但实际情况却很尴尬。所以如果你坚持想要使用源生navigationBar,可以继续尝试,会有办法的。viewController.swift完整代码:二、滑动隐藏/显示有一种很简单的方式,通过判断scrollView的滚动方向来隐藏/显示navigationBar,可以满足一般需求。

  5. Swift中的自定义Flip Segue

    这是我的自定义Segue的代码我认为这有效但实际上只有在已经执行segue时视图才会改变.当“翻转”位于中间时,我该怎么做才能使视图发生变化?

  6. 在Android中阅读广告包

    我正在研究一种广告制造商特定数据的BLE传感器.是否有任何示例代码演示如何在Android中接收广告数据包并解析其有效负载?

  7. 前后端结合实现amazeUI分页效果

    这篇文章主要介绍了前后端结合实现amazeUI分页,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  8. php Illegal string offset 'name'问题及解决

    这篇文章主要介绍了php Illegal string offset 'name'问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  9. 三剑客:offset、client和scroll还傻傻分不清?

    这篇文章主要给大家介绍了三剑客:offset,client和scroll的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  10. 使用HTML CSS实现网页换肤效果(二)

    这篇文章主要介绍了使用HTML CSS实现网页换肤效果(二) 的相关资料,需要的朋友可以参考下

随机推荐

  1. Swift UITextField,UITextView,UISegmentedControl,UISwitch

    下面我们通过一个demo来简单的实现下这些控件的功能.首先,我们拖将这几个控件拖到storyboard,并关联上相应的属性和动作.如图:关联上属性和动作后,看看实现的代码:

  2. swift UISlider,UIStepper

    我们用两个label来显示slider和stepper的值.再用张图片来显示改变stepper值的效果.首先,这三个控件需要全局变量声明如下然后,我们对所有的控件做个简单的布局:最后,当slider的值改变时,我们用一个label来显示值的变化,同样,用另一个label来显示stepper值的变化,并改变图片的大小:实现效果如下:

  3. preferredFontForTextStyle字体设置之更改

    即:

  4. Swift没有异常处理,遇到功能性错误怎么办?

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. 字典实战和UIKit初探

    ios中数组和字典的应用Applicationschedule类别子项类别名称优先级数据包contactsentertainment接触UIKit学习用Swift调用CocoaTouchimportUIKitletcolors=[]varbackView=UIView(frame:CGRectMake(0.0,0.0,320.0,CGFloat(colors.count*50)))backView

  6. swift语言IOS8开发战记21 Core Data2

    上一话中我们简单地介绍了一些coredata的基本知识,这一话我们通过编程来实现coredata的使用。还记得我们在coredata中定义的那个Model么,上面这段代码会加载这个Model。定义完方法之后,我们对coredata的准备都已经完成了。最后强调一点,coredata并不是数据库,它只是一个框架,协助我们进行数据库操作,它并不关心我们把数据存到哪里。

  7. swift语言IOS8开发战记22 Core Data3

    上一话我们定义了与coredata有关的变量和方法,做足了准备工作,这一话我们来试试能不能成功。首先打开上一话中生成的Info类,在其中引用头文件的地方添加一个@objc,不然后面会报错,我也不知道为什么。

  8. swift实战小程序1天气预报

    在有一定swift基础的情况下,让我们来做一些小程序练练手,今天来试试做一个简单地天气预报。然后在btnpressed方法中依旧增加loadWeather方法.在loadWeather方法中加上信息的显示语句:运行一下看看效果,如图:虽然显示出来了,但是我们的text是可编辑状态的,在storyboard中勾选Editable,再次运行:大功告成,而且现在每次单击按钮,就会重新请求天气情况,大家也来试试吧。

  9. 【iOS学习01】swift ? and !  的学习

    如果不初始化就会报错。

  10. swift语言IOS8开发战记23 Core Data4

    接着我们需要把我们的Rest类变成一个被coredata管理的类,点开Rest类,作如下修改:关键字@NSManaged的作用是与实体中对应的属性通信,BinaryData对应的类型是NSData,CoreData没有布尔属性,只能用0和1来区分。进行如下操作,输入类名:建立好之后因为我们之前写的代码有些地方并不适用于coredata,所以编译器会报错,现在来一一解决。

返回
顶部