iOS小结(二)navigation

一、用StoryBoard做navigation

            用StoryBoard拖拽的方式添加Segue(读音seg way)是最简单的页面间跳转的方法,也是最容易上手的,最开始学的时候用的就是这种。

    先在Board中拖入一个NavigationController, 给他制定一个rootView(如红圈1),将程序入口改成指向这个Navigation Controller(红圈2,新建一个项目时就有的,注意不要不小心删了,拖移过来就好), 最后添加想要添加的Navigation就好了,红圈3指示从蓝View跳转到黑View的segue,Show(e.g. push)。

iOS小结(二)navigation_第1张图片

              设置红圈3的属性,设定一个Identifier,假设为“processPhoto”,

iOS小结(二)navigation_第2张图片

           这样只需要在需要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上会出现

二、用代码写navigation

            下面我们尝试用代码改写上面的内容, 那么上面做法就等同于下面的写法:

            在当前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的

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)
    }

三、用presentView做页面间跳转

         跟二中用代码写navigation类似,其实只需要替换push那一行代码为present就好。传参的部分替换原来的prepareForSegue。
   func transit2NextView() {       
        let nextView = EditViewController()
        nextView.nextViewParameter = thisViewParameter   //传参数

        nextView.modalTransitionStyle = UIModalTransitionStyle.CrossDissolve  //改变transition动画
        self.presentViewController(nextView, animated: true, completion: nil)
    }

         这里的区别是我们可以改变transition动画, UIModalTransitionStyle可用的有四种:
enum UIModalTransitionStyle : Int {
    
    case CoverVertical
    case FlipHorizontal
    case CrossDissolve
    @availability(iOS, introduced=3.2)
    case PartialCurl
}

         在下一页要反回到前一页,没有用navigation,是不会自动出现back的导航按钮的,需要自己写一个,这里用一个UIButton来完成。在ViewDidLoad中动态加载back按钮:

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)
​}

          在backButton点击的处理函数中dismiss当前view,也就相当于navigation中的pop,不过这里 注意要将上一view传过来的参数在dismiss前都释放,设为nil就好,一般的参数看不出影响,如果参数是UIImage呢,不释放每次跳转一个来回,这部分memory就会涨几M。
    func backBtnTouchUp(sender: AnyObject) {
        nextViewParameter = nil
        self.dismissViewControllerAnimated(true, completion: nil)
    }
      

四、改变页面跳转的动画 transition animation

         如果不满意默认的动画,有三种较简单的方式可以更改transition的动画。
         对于 三 中 presentView 的方法,可以像三中提到用 modalTransitionStyle 更改为 apple 提供的四种动画。这种方式对navigation不适用。我们可以将 animated 设为 false, disable 系统默认的动画,自己来制定动画,可以用 UIView的 animation blocks 和 CALayer 两种方式来做。 下面简单的举个例子:

         animation block:
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)
      })

         CALayer:
    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)

        当然上面这两种方式,navigation.push 和 presentViewController 自然是都 Ok 的, 分别有哪些可用的 animation style 就请移步 apple 官方文档了。
        这两种动画各自的优缺点,请戳 animation blocks VS CALayer animation

你可能感兴趣的:(ios)