隨着蘋果上次iOS 5的發佈,對話框視圖樣式出如今了咱們面前,直到如今它都沒有發生過很大的變化。下面的代碼片斷展現瞭如何初始化和顯示一個帶有「取消」和「好的」按鈕的對話框視圖。swift
Objective-C版本:安全
UIAlertView *alertview = [[UIAlertView alloc] initWithTitle:@"標題" message:@"這個是UIAlertView的默認樣式" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"好的", nil]; [alertview show];
swift版本和Objective-C版本不一樣,在swift中,alertView的初始化只容許建立擁有一個取消按鈕的對話框視圖。或許您能夠看到帶有otherButtonTitles
的init方法,可是很遺憾,這個方法是沒有辦法經過編譯的。app
var alertView = UIAlertView(title: "標題", message: "這個是UIAlertView的默認樣式", delegate: self, cancelButtonTitle: "取消") alertView.show()
要可以建立和上面Objective-C版本相同的對話框視圖,咱們能夠採起曲線救國的方法,雖然麻煩了些,可是咱們爲了目的能夠不擇手段的,是吧?模塊化
var alertView = UIAlertView() alertView.delegate = selfalertView.title = "標題"alertView.message = "這個是UIAlertView的默認樣式"alertView.addButtonWithTitle("取消") alertView.addButtonWithTitle("好的") alertView.show()
您也能夠經過更改UIAlertView
的alertViewStyle
屬性來實現輸入文字、密碼甚至登陸框的效果。spa
UIAlertViewDelegate
協議擁有響應對話框視圖的按鈕動做的回調方法。還有當文本框內容改變時,調用alertViewShouldEnableOtherButton:
方法可讓按鈕動態地可用或者不可用。代理
要說明一點,蘋果官方如今並不提倡在iOS 8中使用UIAlertView
,取而代之的是UIAlertController
。下面咱們就來介紹UIAlertController
的使用方法。code
在iOS 8中,UIAlertController
在功能上是和UIAlertView
以及UIActionSheet
相同的,UIAlertController
以一種模塊化替換的方式來代替這兩貨的功能和做用。是使用對話框(alert)仍是使用上拉菜單(action sheet),就取決於在建立控制器時,您是如何設置首選樣式的。orm
您能夠比較一下兩種不一樣的建立對話框的代碼,建立基礎UIAlertController
的代碼和建立UIAlertView
的代碼很是類似:server
Objective-C版本:對象
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"標題" message:@"這個是UIAlertController的默認樣式" preferredStyle:UIAlertControllerStyleAlert];
swift版本:
var alertController = UIAlertController(title: "標題", message: "這個是UIAlertController的默認樣式", preferredStyle: UIAlertControllerStyle.Alert)
同建立UIAlertView
相比,咱們無需指定代理,也無需在初始化過程當中指定按鈕。不過要特別注意第三個參數,要肯定您選擇的是對話框樣式仍是上拉菜單樣式。
經過建立UIAlertAction
的實例,您能夠將動做按鈕添加到控制器上。UIAlertAction
由標題字符串、樣式以及當用戶選中該動做時運行的代碼塊組成。經過UIAlertActionStyle
,您能夠選擇以下三種動做樣式:常規(default)、取消(cancel)以及警示(destruective)。爲了實現原來咱們在建立UIAlertView
時建立的按鈕效果,咱們只需建立這兩個動做按鈕並將它們添加到控制器上便可。
Objective-C版本:
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:nil]; [alertController addAction:cancelAction]; [alertController addAction:okAction];
swift版本:
var cancelAction = UIAlertAction(title: "取消", style: UIAlertActionStyle.Cancel, handler: nil) var okAction = UIAlertAction(title: "好的", style: UIAlertActionStyle.Default, handler: nil) alertController.addAction(cancelAction) alertController.addAction(okAction)
最後,咱們只需顯示這個對話框視圖控制器便可:
Objective-C版本:
[self presentViewController:alertController animated:YES completion:nil];
swift版本:
self.presentViewController(alertController, animated: true, completion: nil)
按鈕顯示的次序取決於它們添加到對話框控制器上的次序。通常來講,根據蘋果官方制定的《iOS 用戶界面指南》,在擁有兩個按鈕的對話框中,您應當將取消按鈕放在左邊。要注意,取消按鈕是惟一的,若是您添加了第二個取消按鈕,那麼你就會獲得以下的一個運行時異常:
* Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘UIAlertController can only have one action with a style of UIAlertActionStyleCancel’
異常信息簡潔明瞭,咱們在此就不贅述了。
什麼是「警示」樣式呢?咱們先不着急回答這個問題,先來看一下下面關於「警示」樣式的簡單示例。在這個示例中,咱們將前面的示例中的「好的」按鈕替換爲了「重置」按鈕。
Objective-C版本:
UIAlertAction *resetAction = [UIAlertAction actionWithTitle:@"重置" style:UIAlertActionStyleDestructive handler:nil]; [alertController addAction:resetAction];
swift版本:
var resetAction = UIAlertAction(title: "重置", style: UIAlertActionStyle.Destructive, handler: nil) alertController.addAction(resetAction)
「警示」樣式
能夠看出,咱們新增的那個「重置」按鈕變成了紅色。根據蘋果官方的定義,「警示」樣式的按鈕是用在可能會改變或刪除數據的操做上。所以用了紅色的醒目標識來警示用戶。
UIAlertController
極大的靈活性意味着您沒必要拘泥於內置樣式。之前咱們只能在默認視圖、文本框視圖、密碼框視圖、登陸和密碼輸入框視圖中選擇,如今咱們能夠向對話框中添加任意數目的UITextField
對象,而且可使用全部的UITextField
特性。當您向對話框控制器中添加文本框時,您須要指定一個用來配置文本框的代碼塊。
舉個栗子吧,要從新創建原來的登陸和密碼樣式對話框,咱們能夠向其中添加兩個文本框,而後用合適的佔位符來配置它們,最後將密碼輸入框設置使用安全文本輸入。
Objective-C版本:
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"文本對話框" message:@"登陸和密碼對話框示例" preferredStyle:UIAlertControllerStyleAlert]; [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField){ textField.placeholder = @"登陸"; }]; [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) { textField.placeholder = @"密碼"; textField.secureTextEntry = YES; }];
swift版本:
alertController.addTextFieldWithConfigurationHandler { (textField: UITextField!) -> Void in textField.placeholder = "登陸"} alertController.addTextFieldWithConfigurationHandler { (textField: UITextField!) -> Void in textField.placeholder = "密碼" textField.secureTextEntry = true}
在「好的」按鈕按下時,咱們讓程序讀取文本框中的值。
Objective-C版本:
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { UITextField *login = alertController.textFields.firstObject; UITextField *password = alertController.textFields.lastObject; ... }];
swift版本:
var okAction = UIAlertAction(title: "好的", style: UIAlertActionStyle.Default) { (action: UIAlertAction!) -> Void in var login = alertController.textFields?.first as UITextField var password = alertController.textFields?.last as UITextField}
若是咱們想要實現UIAlertView
中的委託方法alertViewShouldEnableOtherButton:
方法的話可能會有一些複雜。假定咱們要讓「登陸」文本框中至少有3個字符才能激活「好的」按鈕。很遺憾的是,在UIAlertController
中並無相應的委託方法,所以咱們須要向「登陸」文本框中添加一個Observer。Observer模式定義對象間的一對多的依賴關係,當一個對象的狀態發生改變時, 全部依賴於它的對象都獲得通知並被自動更新。咱們能夠在構造代碼塊中添加以下的代碼片斷來實現。
Objective-C版本:
[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField){ ... [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(alertTextFieldDidChange:) name:UITextFieldTextDidChangeNotification object:textField];}];
swift版本:
alertController.addTextFieldWithConfigurationHandler { (textField: UITextField!) -> Void in ... NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("alertTextFieldDidChange:"), name: UITextFieldTextDidChangeNotification, object: textField) }
當視圖控制器釋放的時候咱們須要移除這個Observer,咱們經過在每一個按鈕動做的handler代碼塊(還有其餘任何可能釋放視圖控制器的地方)中添加合適的代碼來實現它。好比說在okAction這個按鈕動做中:
Objective-C版本:
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { ... [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil]; }];
swift版本:
var okAction = UIAlertAction(title: "好的", style: UIAlertActionStyle.Default) { (action: UIAlertAction!) -> Void in ... NSNotificationCenter.defaultCenter().removeObserver(self, name: UITextFieldTextDidChangeNotification, object: nil) }
在顯示對話框以前,咱們要凍結「好的」按鈕
Objective-C版本:
okAction.enabled = NO;
swift版本:
okAction.enabled = false
接下來,在通知觀察者(notification observer)中,咱們須要在激活按鈕狀態前檢查「登陸」文本框的內容。
Objective-C版本:
- (void)alertTextFieldDidChange:(NSNotification *)notification{ UIAlertController *alertController = (UIAlertController *)self.presentedViewController; if (alertController) { UITextField *login = alertController.textFields.firstObject; UIAlertAction *okAction = alertController.actions.lastObject; okAction.enabled = login.text.length > 2; } }
swift版本:
func alertTextFieldDidChange(notification: NSNotification){ var alertController = self.presentedViewController as UIAlertController? if (alertController != nil) { var login = alertController!.textFields?.first as UITextField var okAction = alertController!.actions.last as UIAlertAction okAction.enabled = countElements(login.text) > 2 } }
UIAlertController的登陸和密碼對話框示例
好了,如今對話框的「好的」按鈕被凍結了,除非在「登陸」文本框中輸入3個以上的字符: