1. 程式人生 > >swift詳解之二十二-----------UINavigationController的基本用法和頁面傳值幾種方式

swift詳解之二十二-----------UINavigationController的基本用法和頁面傳值幾種方式

UINavigationController的基本用法和頁面傳值幾種方式

本文介紹UINavigationController基本用法,因為涉及多頁面順便介紹頁面傳值

1、手寫程式碼建立UINavigationController

手寫方式建立很簡單 , 首先建立一個專案 , 預設是從storyboard 載入的。這時候首先去掉預設載入方式 。
這裡寫圖片描述

然後在AppDelegate.swiftdidFinishLaunchingWithOptions 中建立
程式碼如下:


    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject
: AnyObject]?) -> Bool { // Override point for customization after application launch. //在這裡用程式碼來建立NavigationController window = UIWindow(frame: UIScreen.mainScreen().bounds) window?.makeKeyAndVisible() UINavigationBar.appearance().tintColor = UIColor.whiteColor
() UINavigationBar.appearance().barTintColor = UIColor(red: 231.0/255.0, green: 95.0/255.0, blue: 53.0/255.0, alpha: 0.3) //修改導航欄背景色 UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName:UIColor.whiteColor()] //為導航欄設定字型顏色等 let rootCv = ViewController(); let nav = UINavigationController
(rootViewController: rootCv) window?.rootViewController = nav return true }

不要一看這麼多程式碼,其實沒這麼多 。UINavigationBar 開頭的都是為這個導航欄設定的樣式。完全可以不要用預設的,主要就5行 ,前兩行建立window 並讓window顯示 , 後三行建立導航控制器 , 並設定跟控制器 ,然後把window的根控制器設定成這個導航控制器 。這樣就OK了。

執行後發現有黑框 ,暴力解決 ,設定下背景色就行了 。然後再添加個 BarButtonItem 什麼的

  self.view.backgroundColor = UIColor.whiteColor()
        self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Next", style: .Plain, target: self, action: "goNext:")
        self.title = "導航標題"  //設定導航欄title(不是  self.navigationController?.title 哦!)
        self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "我把返回修改了", style: .Plain, target: nil, action: nil)

這裡最後一句是修改了返回的BarButtonItem 文字 , 這裡設定了標題,又加了個rightBarButtonItem 註冊了事件goNext 我們來實現下。

func goNext(sender:AnyObject){
        print("去下一個咯")
        let mainVc = UIStoryboard(name: "Third", bundle: nil).instantiateViewControllerWithIdentifier("three") as UIViewController
        self.navigationController?.pushViewController(mainVc, animated: true)
    }

一看這個又暈了 ,中間那些是什麼呀 。。首先我們從storyboard建立了一個控制器(手寫的看過了,為了多學點知識) ,這裡的instantiateViewControllerWithIdentifier 中的three 如下設定
這裡寫圖片描述

然後push進去 。 導航控制器是採用棧的方式先進後出 , 用push和pop 。那個storyboard 中很簡單就放了一個Label 和一個Button ,等會再介紹那個 ,先看看效果

這裡寫圖片描述

然後我們給那個按鈕也註冊個事件 ,這裡直接拖就行了。
實現如下

 @IBAction func showTabBar(sender: AnyObject) {
        let mainVc = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("second") as! UINavigationController
        self.presentViewController(mainVc, animated: true) { () -> Void in

        }
    }

這裡還是從storyboard 中載入控制器 , 但是卻用了presentViewController ,因為導航控制器不讓push導航控制器 ,這邊主要是像演示通過storyboard 建立導航控制器

2、 通過storyboard 建立UINavigationController

如果你跟我一樣用Main.storyboard , 可以先刪除預設的那個控制器 , 從右邊拖出來一個UINavigationController ,這個會預設帶一個UITableViewController , 刪掉,拖一個普通的UIViewController 。選中UINavigationController 右鍵拖到那個UIViewController 選擇rootViewController就行了 。然後可以自己拖BarButtonItem 也可以在程式碼中寫 。我這邊是拖進來的
這裡寫圖片描述

就是這麼拖的 , 因為我這邊拖過了就不再拖了,註冊事件也是拖,跟button一樣的。就不再演示 。

這時候執行效果。
這裡寫圖片描述

這裡是用presentViewController 彈出的返回用dismissViewControllerAnimated

 @IBAction func goBack(sender: UIBarButtonItem) {
        self.dismissViewControllerAnimated(true) { () -> Void in
            print("返回")
        }
    }

導航控制器基本操作很簡單 ,下面看下載不同頁面中正反傳值

3、頁面傳值的幾種方式

  • 正面反面傳值 (協議)

大家看到那個頁面我們放了三個按鈕和一個輸入框 ,按鈕都註冊了事件。然後手寫了一個新的控制器 ,裡面是一個返回按鈕和幾個label 還有一個輸入框 。

當我們點選第一個按鈕的時候進入下一個控制器 , push進去的 ,那個控制器有個方法 。

func  passParams(tmpStr: String){
        lb.text = tmpStr
    }

所以我們在push前,呼叫這個方法正面傳值, 當然你可以直接給他的共有屬性賦值。

let vc = ViewControllerFour()
let value = tf1.text
vc.passParams(value!)
        self.navigationController?.pushViewController(vc, animated: true)

很簡單, lb.text = tmpStr 會把傳過來的值賦值給label

反向傳值這裡使用了代理,先宣告一個協議

protocol ParameterDelegate{
    func passParams(tmpStr: String)
}

然後在我們第一個頁面實現這個協議 。實現對應的方法

    func passParams(tmpStr: String){
        tf1.text = tmpStr
    }

然後在第二頁面宣告代理為自己的變數

 var delegate:ParameterDelegate?

在push之前把自己設定為第二個頁面的代理

  let vc = ViewControllerFour()
 vc.delegate = self  //通過代理進行反向傳值
 let value = tf1.text
 vc.passParams(value!)
        self.navigationController?.pushViewController(vc, animated: true)

注意到沒,比剛才多一句話

OK ,這樣就搞定了。來看效果 !
這裡寫圖片描述

  • 第二種方法 (通過segue進行的傳值)

直接通過storyboard拖拽, 話說storyboard做介面還真方便 , 需要好好研究一下

重新拖一個控制器然後連線,我這邊已經拖好了,我就演示下連線

這裡寫圖片描述
然後在程式碼中

  //通過segue進行的傳值
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "toshow" {
            let vc = segue.destinationViewController as! ViewControllerTwoShow
            vc.tmpStr = tf1.text
            //vc.setValue(tf1, forKey: "tmpStr")
        }
    }

在目標控制器中定義了變數tmpStr (後面會把程式碼分享出來)

看下效果
這裡寫圖片描述

  • 通過通知的方式
    let vc = ViewControllerFour()
        vc.delegate = self  //通過代理進行反向傳值

        self.presentViewController(vc, animated: true) { () -> Void in
//釋出一條通知NSNotificationCenter.defaultCenter().postNotificationName("DefaultNotif", object:self.tf1.text)
        }

先註冊一個通知 , 展現介面完成的時候釋出一個通知 。在另一個介面的viewWillAppear接收通知 。

 override func viewWillAppear(animated: Bool) {
        //self.navigationController?.hidesBarsOnSwipe = true
        self.navigationController?.setNavigationBarHidden(true, animated: true) //隱藏導航欄

        NSNotificationCenter.defaultCenter().addObserver(self, selector: "doSomeT:", name: "DefaultNotif", object: nil)
    }

對應方法

func doSomeT(title:NSNotification){
        lb1.text = title.object as? String
    }

看看效果 :
這裡寫圖片描述

大概就這麼多吧 , 最後把原始碼發上來吧, 語文不太好估計沒講清楚,大家可以看原始碼。以後原始碼都放這個地址了(覺得還行的話給個star 哦)
githubSwiftStudy