用StoryBoard拖拽的方式添加Segue(读音seg way)是最简单的页面间跳转的方法,也是最容易上手的,最开始学的时候用的就是这种。
先在Board中拖入一个NavigationController, 给他制定一个rootView(如红圈1),将程序入口改成指向这个Navigation Controller(红圈2,新建一个项目时就有的,注意不要不小心删了,拖移过来就好), 最后添加想要添加的Navigation就好了,红圈3指示从蓝View跳转到黑View的segue,Show(e.g. push)。
设置红圈3的属性,设定一个Identifier,假设为“processPhoto”,
这样只需要在需要transition的地方加上:
performSegueWithIdentifier("processPhoto", sender: nil)
就可以进行跳转了,这样做的好处是navigationController自己管理了一个stack来接受ViewController的push和pop, 而且不用自己写这部分代码了。
如果要在当前VC跳转transit到另一个VC过程中传参数,在当前ViewController的class内override下面这个function:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if (segue.identifier == "processPhoto") { let svc = segue.destinationViewController as! NextViewController svc.nextViewParameter = thisViewParameter } }
上面的做法很方便的帮我们完成了页面跳转,管理页面间导航,那这个面板的背后都做了什么呢?
上面说 Navigation Controller 维护了一个View Controller 的 stack,每加一个上面这种 Push 的 Segue, 就把上面的View堆到栈顶,同时上面的 View 的navigationBar上会出现<Back 这个 BarItem 按钮,点击这个按钮就返回到上一个View, 将当前View 从栈顶 Pop 出去。同时这个过程加上从左到右,从右到左的 transition 动画。而这些都只是拖进一个小小的 Segue 引入的。
下面我们尝试用代码改写上面的内容, 那么上面做法就等同于下面的写法:
在当前ViewController该跳转的地方push:
func transit2NextView() { let storyboard = UIStoryboard(name: "Main", bundle: nil) let nextView = storyboard.instantiateViewControllerWithIdentifier("EditView") as! NextViewController nextView.nextViewParameter = thisViewParameter //传参数 self.navigationController?.pushViewController(nextView, animated: true) }在下一个View的 <Back 导航条按钮处理函数中pop:
func back2PrevView() { self.navigationController?.popViewControllerAnimated(true) }
上面的方法和 一 中用storyboard的做法结果是一样的。也可以调用 popToRootViewControllerAnimated 方法 pop 回 rootView。
上面的跳转写法还是用了storyboard做初始化,如果NextViewController写了requiredinit(coder aDecoder:NSCoder) { } , 就一定要用一个storyboard的ID初始化VIewController, 如果不定义这个方法或者不用required关键字,还是可以像下面这样简单的构造一个ViewController的。
func transit2NextView() { let nextView = NextViewController() nextView.nextViewParameter = thisViewParameter //传参数 self.navigationController?.pushViewController(nextView, animated: true) }
func transit2NextView() { let nextView = EditViewController() nextView.nextViewParameter = thisViewParameter //传参数 nextView.modalTransitionStyle = UIModalTransitionStyle.CrossDissolve //改变transition动画 self.presentViewController(nextView, animated: true, completion: nil) }
enum UIModalTransitionStyle : Int { case CoverVertical case FlipHorizontal case CrossDissolve @availability(iOS, introduced=3.2) case PartialCurl }
override func viewDidLoad() { super.viewDidLoad() let backButton: UIButton = UIButton(frame: CGRectMake(12, 12, 45, 45)) backButton.imageEdgeInsets = UIEdgeInsetsMake(12.0 , 12.0, 12.0 , 12.0) backButton.setImage(UIImage(named:"cross")!, forState: UIControlState.Normal) backButton.layer.cornerRadius = curButton.frame.size.width/2 backButton.backgroundColor = UIColor.whiteColor() backButton.addTarget(self, action:"backBtnTouchUp:", forControlEvents: UIControlEvents.TouchUpInside) self.view.addSubview(backButton) }
func backBtnTouchUp(sender: AnyObject) { nextViewParameter = nil self.dismissViewControllerAnimated(true, completion: nil) }
UIView.animateWithDuration(0.75, animations: { () -> Void in UIView.setAnimationCurve(UIViewAnimationCurve.EaseInOut) self.navigationController?.pushViewController(nextView, animated: false) UIView.setAnimationTransition(UIViewAnimationTransition.CurlDown, forView: self.navigationController!.view, cache: false) })
let transition = CATransition() transition.duration = 0.5 transition.type = kCATransitionFade self.navigationController?.view.layer.addAnimation(transition, forKey: nil) let nextView = self.storyboard?.instantiateViewControllerWithIdentifier("nextView") as! NextViewController self.navigationController?.pushViewController(nextView, animated: false)