如何使用Swift在iOS中从右到左呈现视图控制器

Uma*_*zal 70 ios segue swift swift2

我正在使用presentViewController来呈现新的屏幕

let dashboardWorkout = DashboardWorkoutViewController()
presentViewController(dashboardWorkout, animated: true, completion: nil)
Run Code Online (Sandbox Code Playgroud)

这从底部到顶部呈现新屏幕,但我希望它从右到左呈现而不使用UINavigationController.

我使用Xib而不是故事板,所以我该怎么做?

mrv*_*nzo 140

没关系,如果它是xib或者storyboard您正在使用.通常,当您将视图控制器推入到演示者时,会使用从右到左的过渡UINavigiationController.

UPDATE

增加了计时功能 kCAMediaTimingFunctionEaseInEaseOut

示例项目斯威夫特4实现加入GitHub上


Swift 3和4.2

let transition = CATransition()
transition.duration = 0.5
transition.type = CATransitionType.push
transition.subtype = CATransitionSubtype.fromRight
transition.timingFunction = CAMediaTimingFunction(name:CAMediaTimingFunctionName.easeInEaseOut)
view.window!.layer.add(transition, forKey: kCATransition)
present(dashboardWorkout, animated: false, completion: nil)
Run Code Online (Sandbox Code Playgroud)


ObjC

CATransition *transition = [[CATransition alloc] init];
transition.duration = 0.5;
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromRight;
[transition setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[self.view.window.layer addAnimation:transition forKey:kCATransition];
[self presentViewController:dashboardWorkout animated:false completion:nil];
Run Code Online (Sandbox Code Playgroud)


Swift 2.x

let transition = CATransition()
transition.duration = 0.5
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromRight
transition.timingFunction = CAMediaTimingFunction(name:kCAMediaTimingFunctionEaseInEaseOut)
view.window!.layer.addAnimation(transition, forKey: kCATransition)
presentViewController(dashboardWorkout, animated: false, completion: nil)
Run Code Online (Sandbox Code Playgroud)

在这种自定义转换的情况下,似乎方法中的animated参数presentViewController并不重要.它可以是任何值,true或者false.

  • 我尝试在自定义 UIStoryboardSegue 的 perform() 方法中使用 Swift3 代码,问题是 - 在同一个视图上完成转换,然后出现第二个视图。对此有什么想法吗? (2认同)
  • 通常,当我使用此方法时,源VC正在逐渐淡出。如何删除该淡入淡出效果,使其具有与推动画一样的效果? (2认同)
  • 如果你将"动画"变为"真实",它也会有一个略微向上的动画.我建议将其设置为"false" (2认同)

小智 54

存在/解雇的完整代码,Swift 3

extension UIViewController {

    func presentDetail(_ viewControllerToPresent: UIViewController) {
        let transition = CATransition()
        transition.duration = 0.25
        transition.type = kCATransitionPush
        transition.subtype = kCATransitionFromRight
        self.view.window!.layer.add(transition, forKey: kCATransition)

        present(viewControllerToPresent, animated: false)
    }

    func dismissDetail() {
        let transition = CATransition()
        transition.duration = 0.25
        transition.type = kCATransitionPush
        transition.subtype = kCATransitionFromLeft
        self.view.window!.layer.add(transition, forKey: kCATransition)

        dismiss(animated: false)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 支持你的答案,因为它也有关闭功能 (3认同)
  • 请更具体。解释更多 ! (2认同)

Hot*_*ard 26

阅读所有答案,看不到正确的解决方案.正确的方法是为呈现的VC委托制作自定义UIViewControllerAnimatedTransitioning.

所以它假设要做更多的步骤,但结果更加可定制,并且没有一些副作用,例如从视图移动到显示的视图.

所以,假设你有一些ViewController,并且有一种呈现方法

var presentTransition: UIViewControllerAnimatedTransitioning?
var dismissTransition: UIViewControllerAnimatedTransitioning?    

func showSettings(animated: Bool) {
    let vc = ... create new vc to present

    presentTransition = RightToLeftTransition()
    dismissTransition = LeftToRightTransition()

    vc.modalPresentationStyle = .custom
    vc.transitioningDelegate = self

    present(vc, animated: true, completion: { [weak self] in
        self?.presentTransition = nil
    })
}
Run Code Online (Sandbox Code Playgroud)

presentTransitiondismissTransition用于动画视图控制器.因此,您采用ViewController来UIViewControllerTransitioningDelegate:

extension ViewController: UIViewControllerTransitioningDelegate {
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return presentTransition
    }

    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return dismissTransition
    }
}
Run Code Online (Sandbox Code Playgroud)

所以最后一步是创建自定义转换:

class RightToLeftTransition: NSObject, UIViewControllerAnimatedTransitioning {
    let duration: TimeInterval = 0.25

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

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

        container.addSubview(toView)
        toView.frame.origin = CGPoint(x: toView.frame.width, y: 0)

        UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: {
            toView.frame.origin = CGPoint(x: 0, y: 0)
        }, completion: { _ in
            transitionContext.completeTransition(true)
        })
    }
}

class LeftToRightTransition: NSObject, UIViewControllerAnimatedTransitioning {
    let duration: TimeInterval = 0.25

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

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

        container.addSubview(fromView)
        fromView.frame.origin = .zero

        UIView.animate(withDuration: duration, delay: 0, options: .curveEaseIn, animations: {
            fromView.frame.origin = CGPoint(x: fromView.frame.width, y: 0)
        }, completion: { _ in
            fromView.removeFromSuperview()
            transitionContext.completeTransition(true)
        })
    }
}
Run Code Online (Sandbox Code Playgroud)

在该代码视图中,控制器在当前上下文中呈现,您可以从该点进行自定义.您也可以看到自定义UIPresentationController也很有用(传入使用UIViewControllerTransitioningDelegate)


Pho*_*int 13

您也可以使用自定义segue.

斯威夫特3

class SegueFromRight: UIStoryboardSegue
{ 
    override func perform()
    {
    let src = self.source
    let dst = self.destination

    src.view.superview?.insertSubview(dst.view, aboveSubview: src.view)
    dst.view.transform = CGAffineTransform(translationX: src.view.frame.size.width, y: 0)

    UIView.animate(withDuration: 0.25,
                   delay: 0.0,
                   options: UIViewAnimationOptions.curveEaseInOut,
                   animations: {
                    dst.view.transform = CGAffineTransform(translationX: 0, y: 0)
    },
                   completion: { finished in
                    src.present(dst, animated: false, completion: nil)
    }
    )
}
}
Run Code Online (Sandbox Code Playgroud)


Lio*_*ion 7

试试这个,

    let animation = CATransition()
    animation.duration = 0.5
    animation.type = kCATransitionPush
    animation.subtype = kCATransitionFromRight
     animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
    vc.view.layer.addAnimation(animation, forKey: "SwitchToView")

    self.presentViewController(vc, animated: false, completion: nil)
Run Code Online (Sandbox Code Playgroud)

在您的情况下vc,这是viewcontroller dashboardWorkout.

  • 谢谢,但是下一个VC突然出现而不是从右到左出现.我改变了动画持续时间但仍然相同 (2认同)

Fab*_*bio 5

导入 UIKit 并为 UIViewController 创建一个扩展:

extension UIViewController {
func transitionVc(vc: UIViewController, duration: CFTimeInterval, type: CATransitionSubtype) {
    let customVcTransition = vc
    let transition = CATransition()
    transition.duration = duration
    transition.type = CATransitionType.push
    transition.subtype = type
    transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
    view.window!.layer.add(transition, forKey: kCATransition)
    present(customVcTransition, animated: false, completion: nil)
}}
Run Code Online (Sandbox Code Playgroud)

简单调用后:

let vC = YourViewController()
transitionVc(vc: vC, duration: 0.5, type: .fromRight)
Run Code Online (Sandbox Code Playgroud)

从左到右:

let vC = YourViewController()
transitionVc(vc: vC, duration: 0.5, type: .fromleft)
Run Code Online (Sandbox Code Playgroud)

您可以使用您喜欢的持续时间更改持续时间...