swift詳解之二十二-----------UINavigationController的基本用法和頁面傳值幾種方式
UINavigationController的基本用法和頁面傳值幾種方式
本文介紹UINavigationController基本用法,因為涉及多頁面順便介紹頁面傳值
1、手寫程式碼建立UINavigationController
手寫方式建立很簡單 , 首先建立一個專案 , 預設是從storyboard
載入的。這時候首先去掉預設載入方式 。
然後在AppDelegate.swift
的didFinishLaunchingWithOptions
中建立
程式碼如下:
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