iOS Segue – 从左到右 –

我已经读过segues上的其他post,但没有解决我的问题。

简而言之,我的ViewController是有序的,就像一本书。 我希望向后转换(例如:从第9页到第8页)以始终呈现(从上向下滑动)。 我希望向前转换(从第9页到第10页)从右到左呈现。

是的,我的导航控制器后退button(左上angular)是这样呈现的,如果你是一页接一页的翻页。 但是,如果您从索引中跳转,那么导航控制器上的返回function会将您带回索引。

我的目标是,如果用户从索引跳转到第9页(例如),然后向右滑动,则会将页面向右滑动并显示第8页。一旦在第8页上,如果他们向左轻弹页面被轻弹到左边,他们将再次在第9页。

我所有的ViewController都是默认的,通过从右向左滑动来呈现。

例如:把它想象成一本书,如果我使用索引跳到第4章,然后向右滑动并从堆栈popup一个视图,我会回到索引处。 但是,如果你在第四章,第394页,而且你向右滑动,你就不想回到索引了! 你想去第三章第393页的最后一页! 所以导航堆栈对我没有帮助。

结束示例

详细信息:1.我使用新的Xcode“显示”button点击切换ViewControllers。

  1. 我正在使用导航控制器,左上angular的“返回”buttonfunction。 这使用导航堆栈,并正常工作。

  2. 不过,我有我自己的自定义导航栏在底部(后退button,主页button,索引button,前进button)和手势。 这些就是我想要的书籍function。

  3. 快速编码。

  4. 使用Xcode 6.3

我读过那里有animation代码。 我读过可以使用的深入的程序化转换。 看起来很疯狂,没有简单的方法来select我想要从左侧展示的赛段,并轻松地反转animation。

谢谢!

尝试日志:

 I tried DCDC's code: UIView.transitionWithView(self.window!, duration: 0.5, options:.TransitionFlipFromLeft, animations: { () -> Void in self.window!.rootViewController = mainVC }, completion:nil) 

当我将DCDC的代码插入到IBAction ,返回此错误,以便进行反向扫描

当我将DCDC的代码插入到IBAction中时,返回此错误,以便进行反向扫描

这是我如何达到效果,而不需要导航控制器。 试试这个:

Swift 4:

 import UIKit class SegueFromLeft: 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: .curveEaseInOut, animations: { dst.view.transform = CGAffineTransform(translationX: 0, y: 0) }, completion: { finished in src.present(dst, animated: false, completion: nil) } ) } } 

Swift 3:

 import UIKit class SegueFromLeft: UIStoryboardSegue { override func perform() { let src = self.sourceViewController let dst = self.destinationViewController src.view.superview?.insertSubview(dst.view, aboveSubview: src.view) dst.view.transform = CGAffineTransformMakeTranslation(-src.view.frame.size.width, 0) UIView.animateWithDuration(0.25, delay: 0.0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { dst.view.transform = CGAffineTransformMakeTranslation(0, 0) }, completion: { finished in src.presentViewController(dst, animated: false, completion: nil) } ) } } 

然后在故事板中,点击你想改变的segue。 在属性检查器中将types更改为“Custom”,并将类更改为“SegueFromLeft”

这是一个可以用来在Swift中执行从左到右继续的自定义segue类。 它需要QuartzCore框架和最小的animation。

Swift 2.2

 import UIKit import QuartzCore class SegueFromLeft: UIStoryboardSegue { override func perform() { let src: UIViewController = self.sourceViewController let dst: UIViewController = self.destinationViewController let transition: CATransition = CATransition() let timeFunc : CAMediaTimingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) transition.duration = 0.25 transition.timingFunction = timeFunc transition.type = kCATransitionPush transition.subtype = kCATransitionFromLeft src.navigationController!.view.layer.addAnimation(transition, forKey: kCATransition) src.navigationController!.pushViewController(dst, animated: false) } } 

Swift 3.0

 import UIKit import QuartzCore class SegueFromLeft: UIStoryboardSegue { override func perform() { let src: UIViewController = self.source let dst: UIViewController = self.destination let transition: CATransition = CATransition() let timeFunc : CAMediaTimingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) transition.duration = 0.25 transition.timingFunction = timeFunc transition.type = kCATransitionPush transition.subtype = kCATransitionFromLeft src.navigationController!.view.layer.add(transition, forKey: kCATransition) src.navigationController!.pushViewController(dst, animated: false) } } 

“返回”button仍将出现在转换后的视图控制器的导航栏中,但您可以轻松地禁用/configuration该视图控制器的导航控制器。

在Swift 3中更新了接受的答案:

 import UIKit class SegueFromLeft: 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) } ) } } 

您可以在transitionWithView方法中使用预定义的types转换

 UIView.transitionWithView(self.window!, duration: 0.5, options:.TransitionFlipFromLeft, animations: { () -> Void in self.window!.rootViewController = mainVC }, completion:nil) 

我想.TransitionFlipFromLeft是所需的

要完成任务,将一个新的视图控制器拖到故事板,并用一些id命名。 这将成为转型的目的地。

然后从代码实例化这个视图控制器

 let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil) let mainVC = storyboard.instantiateViewControllerWithIdentifier("someViewController") as! UIViewController 

你可以在IBAction里面或者在ViewDidLoad中做这个,但是IBAction可能是更好的select。 请注意为故事板和视图控制器input正确的标识符。 另外,你必须声明你的appDelegate实例。 这是实施的IBAction

 @IBAction func push(sender: UIButton) { let storyboard = UIStoryboard(name: "Main", bundle: nil) let mainVC = storyboard.instantiateViewControllerWithIdentifier("secondVC") as! UIViewController let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate UIView.transitionWithView(appDelegate.window!, duration: 0.5, options: .TransitionFlipFromLeft , animations: { () -> Void in appDelegate.window!.rootViewController = mainVC }, completion:nil) } 

如果这不是你所期望的,可能你可能想制作一个自定义的animation。 这篇文章真的很有用: http : //mathewsanders.com/animated-transitions-in-swift/

这听起来像你只是试图从UINavigationController的堆栈popup一个视图控制器,就像默认的后退button。

你可以做两件事之一。 最简单的方法是将自定义后退button连接到调用popViewControllerAnimated()的IBAction:

 @IBAction func tappedCustomBackButton(sender: AnyObject) { self.navigationController?.popViewControllerAnimated(true) } 

或者你可以创build一个从你的第二个视图控制器退到第一。

接受的答案已更新为Swift 3 (截至2017年6月)

从左到右依次为

 import UIKit class SegueFromLeft: UIStoryboardSegue { override func perform() { let src = self.source //new enum let dst = self.destination //new enum src.view.superview?.insertSubview(dst.view, aboveSubview: src.view) dst.view.transform = CGAffineTransform(translationX: -src.view.frame.size.width, y: 0) //Method call changed UIView.animate(withDuration: 0.25, delay: 0.0, options: UIViewAnimationOptions.curveEaseInOut, animations: { dst.view.transform = CGAffineTransform(translationX: 0, y: 0) }) { (finished) in src.present(dst, animated: false, completion: nil) //Method call changed } } } 

从右到左争论

 import UIKit 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*2, y: 0) //Double the X-Axis UIView.animate(withDuration: 0.25, delay: 0.0, options: UIViewAnimationOptions.curveEaseInOut, animations: { dst.view.transform = CGAffineTransform(translationX: 0, y: 0) }) { (finished) in src.present(dst, animated: false, completion: nil) } } } 

在我的情况下,我曾经做一个侧边栏菜单…

我创build了一个新的视图控制器和两个海关部门

打开菜单:

 import Foundation import UIKit class SegueFromLeft: UIStoryboardSegue { override func perform() { let src = self.source as UIViewController let dst = self.destination as UIViewController 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) } ) } } 

closures菜单:

 import Foundation import UIKit class SegueFromRight: UIStoryboardSegue { override func perform() { let src = self.source as UIViewController let dst = self.destination as UIViewController src.view.superview?.insertSubview(dst.view, belowSubview: src.view) src.view.transform = CGAffineTransform(translationX: 0, y: 0) UIView.animate(withDuration: 0.25, delay: 0.0, options: UIViewAnimationOptions.curveEaseInOut, animations: { src.view.transform = CGAffineTransform(translationX: -src.view.frame.size.width, y: 0) }, completion: { finished in src.dismiss(animated: false, completion: nil) } ) } } 

我希望它帮助你…

来自右边。你可以像下面那样重写segue中的执行函数。 把这个函数放在一个自定义的segue类中,然后把这个类分配给segue。 它将适用于两个控制器与导航控制器和没有导航控制器

 override func perform() { let src = self.sourceViewController print(src) let dst = self.destinationViewController print(dst) src.view.superview?.insertSubview(dst.view, aboveSubview: src.view) dst.view.transform = CGAffineTransformMakeTranslation(src.view.frame.size.height, 0) UIView.animateWithDuration(0.35, delay: 0.0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { dst.view.transform = CGAffineTransformMakeTranslation(0, 0) }, completion: { finished in if let navController = src.navigationController { navController.pushViewController(dst, animated: false) } else { src.presentViewController(dst, animated: false, completion: nil) } } ) } 

如果你想从左边继续使用这个

 CGAffineTransformMakeTranslation(-src.view.frame.size.height, 0) 

嘿家伙,我有完整的解决scheme,只是复制和过去这个代码写迅速3。

 func menu(){ let storyboard = UIStoryboard(name: "Main", bundle: nil) let vc = storyboard.instantiateViewController(withIdentifier: "MyAccountViewController") as! MyAccountViewController let transition: CATransition = CATransition() let timeFunc : CAMediaTimingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) transition.duration = 0.5 transition.timingFunction = timeFunc transition.type = kCATransitionPush transition.subtype = kCATransitionFromLeft self.navigationController?.view.layer.add(transition, forKey: kCATransition) self.navigationController?.pushViewController(vc, animated: false) } 

注意:使用“MyAccountViewController”文本更改ViewController的名称。