UIAlertController

轉(zhuǎn)自星夜暮晨的博客

對(duì)話框樣式

1`創(chuàng)建Alert控制器

Objective-C版本:

UIAlertController?*alertController?=?[UIAlertController?alertControllerWithTitle:@"標(biāo)題"message:@"這個(gè)是UIAlertController的默認(rèn)樣式"preferredStyle:UIAlertControllerStyleAlert];

swift版本:

var alertController?=?UIAlertController(title:"標(biāo)題",?message:"這個(gè)是UIAlertController的默認(rèn)樣式", preferredStyle:UIAlertControllerStyle.Alert

)

2`創(chuàng)建AlertAction實(shí)例并添加到控制器上

通過(guò)創(chuàng)建UIAlertAction的實(shí)例驻右,您可以將動(dòng)作按鈕添加到控制器上。UIAlertAction由標(biāo)題字符串唱歧、樣式以及當(dāng)用戶選中該動(dòng)作時(shí)運(yùn)行的

代碼塊組成韧献。通過(guò)UIAlertActionStyle吧黄,您可以選擇如下三種動(dòng)作樣式:常規(guī)(default)驹溃、取消(cancel)以及警示(destruective)舱殿。

Objective-C版本:

UIAlertAction?*cancelAction?=?[UIAlertAction?actionWithTitle:@"取消"style:UIAlertActionStyleCancel?handler:nil];

UIAlertAction?*defaultAction?=?[UIAlertAction?actionWithTitle:@"好的"style:UIAlertActionStyleDefault?handler:nil];

-------

[alertController?addAction:cancelAction];

[alertController?addAction:okAction];


swift版本:

var cancelAction?=?UIAlertAction(title:"取消",?style:?UIAlertActionStyle.Cancel,?handler:?nil)

var defaultAction?=?UIAlertAction(title:"好的",?style:?UIAlertActionStyle.Default,?handler:?nil)

--------

alertController.addAction(cancelAction)

alertController.addAction(okAction)

3`顯示該對(duì)話框控制器

Objective-C版本:

[self?presentViewController:alertController?animated:YES?completion:nil];

swift版本:

self.presentViewController(alertController,?animated:true,?completion:?nil)

對(duì)話框樣式

按鈕顯示的次序取決于它們添加到對(duì)話框控制器上的次序饲宛。一般來(lái)說(shuō),根據(jù)蘋果官方制定的《iOS 用戶界面指南》概作,在擁有兩個(gè)按鈕的對(duì)話框中腋妙,您應(yīng)當(dāng)將取消按鈕放在左邊。要注意讯榕,取消按鈕是唯一的骤素,如果您添加了第二個(gè)取消按鈕匙睹,那么你就會(huì)得到一個(gè)運(yùn)行時(shí)異常。

“警示”樣式

我們將前面的示例中的“好的”按鈕替換為了“重置”按鈕济竹。

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)

警示樣式

可以看出痕檬,我們新增的那個(gè)“重置”按鈕變成了紅色。根據(jù)蘋果官方的定義送浊,“警示”樣式的按鈕是用在可能會(huì)改變或刪除數(shù)據(jù)的操作上梦谜。因此用了紅色的醒目標(biāo)識(shí)來(lái)警示用戶。

文本對(duì)話框

UIAlertController極大的靈活性意味著您不必拘泥于內(nèi)置樣式罕袋。以前我們只能在默認(rèn)視圖改淑、文本框視圖碍岔、密碼框視圖浴讯、登錄和密碼輸入框視圖中選擇,現(xiàn)在我們可以向?qū)υ捒蛑?b>添加任意數(shù)目的UITextField對(duì)象蔼啦,并且可以使用所有的UITextField特性榆纽。

舉個(gè)例子吧:

Objective-C版本:

UIAlertController?*alertController?=?[UIAlertController?alertControllerWithTitle:@"文本對(duì)話框"message:@"登錄和密碼對(duì)話框示例"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?*defaultAction?=?[UIAlertAction?actionWithTitle:@"好的"style:UIAlertActionStyleDefault?handler:^(UIAlertAction?*action)?{

UITextField?*login?=?alertController.textFields.firstObject;

UITextField?*password?=?alertController.textFields.lastObject;

NSLog(@"%@",login.text);

NSLog(@"%@",password.text);

}];


swift版本:

var defaultAction?=?UIAlertAction(title:"好的",?style:?UIAlertActionStyle.Default)?{

(action:?UIAlertAction!)?->?Void in

var login?=?alertController.textFields?.first?as?UITextField

var password?=?alertController.textFields?.last?as?UITextField

}

假定我們要讓“登錄”文本框中至少有3個(gè)字符才能激活“好的”按鈕奈籽。因此我們需要向“登錄”文本框中添加一個(gè)Observer。Observer模式是定義對(duì)象間的一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴于它的對(duì)象都得到通知并被自動(dòng)更新鸵赫。我們可以在構(gòu)造代碼塊(添加UITextField控件)中添加如下的代碼片段來(lái)實(shí)現(xiàn)衣屏。

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)

}

當(dāng)視圖控制器釋放的時(shí)候我們需要移除這個(gè)Observer,我們通過(guò)在每個(gè)按鈕動(dòng)作的handler代碼塊(還有其他任何可能釋放視圖控制器的地方)中添加合適的代碼來(lái)實(shí)現(xiàn)它辩棒。比如說(shuō)在defaultAction這個(gè)按鈕動(dòng)作中:

Objective-C版本:

UIAlertAction?*defaultAction?=?[UIAlertAction?actionWithTitle:@"好的"style:UIAlertActionStyleDefault?handler:^(UIAlertAction?*action)

{

...

[[NSNotificationCenter?defaultCenter]?removeObserver:self?name:UITextFieldTextDidChangeNotification?object:nil];

}];


swift版本:

varokAction?=?UIAlertAction(title:"好的",?style:?UIAlertActionStyle.Default)?{

(action:?UIAlertAction!)?->?Voidin

...

NSNotificationCenter.defaultCenter().removeObserver(self,?name:?UITextFieldTextDidChangeNotification,?object:?nil)

}

在顯示對(duì)話框之前狼忱,我們要凍結(jié)“好的”按鈕

Objective-C版本:

defaultAction.enabled?=?NO;

swift版本:

defaultAction.enabled =false

接下來(lái),在通知觀察者(notification observer)中一睁,我們需要在激活按鈕狀態(tài)前檢查“登錄”文本框的內(nèi)容钻弄。

Objective-C版本:

-?(void)alertTextFieldDidChange:(NSNotification?*)notification

{

UIAlertController?*alertController?=?(UIAlertController?*)self.presentedViewController;

if(alertController)?

??? {

UITextField?*login?=?alertController.textFields.firstObject;

UIAlertAction?*defaultAction?=?alertController.actions.lastObject;

defaultAction.enabled = login.text.length > 2;? ?

???? }

}

swift版本:

func?alertTextFieldDidChange(notification:?NSNotification)

{

varalertController?=?self.presentedViewController?as?UIAlertController?

if(alertController?!=?nil)

? ? ? {

varlogin?=?alertController!.textFields?.first?as?UITextField

varokAction?=?alertController!.actions.last?as?UIAlertAction

okAction.enabled?=?countElements(login.text)?>?2

????? }

}

UIAlertController的登錄和密碼對(duì)話框示例

好了,現(xiàn)在對(duì)話框的“好的”按鈕被凍結(jié)了者吁,除非在“登錄”文本框中輸入3個(gè)以上的字符

上拉菜單

當(dāng)需要給用戶展示一系列選擇的時(shí)候窘俺,上拉菜單就能夠派上大用場(chǎng)了。和對(duì)話框不同复凳,上拉菜單的展示形式和設(shè)備大小有關(guān)瘤泪。

在iPhone上(緊縮寬度),上拉菜單從屏幕底部升起育八。在iPad上(常規(guī)寬度)均芽,上拉菜單以彈出框的形式展現(xiàn)。

創(chuàng)建上拉菜單的方式和創(chuàng)建對(duì)話框的方式非常類似单鹿,唯一的區(qū)別是它們的形式掀宋。

Objective-C版本:

UIAlertController?*alertController?=?[UIAlertController?alertControllerWithTitle:@"保存或刪除數(shù)據(jù)"message:@"刪除數(shù)據(jù)將不可恢復(fù)"preferredStyle:?UIAlertControllerStyleActionSheet];

swift版本:

var alertController?=?UIAlertController(title:"保存或刪除數(shù)據(jù)",?message:"刪除數(shù)據(jù)將不可恢復(fù)",?preferredStyle:?UIAlertControllerStyle.ActionSheet)

添加按鈕動(dòng)作的方式和對(duì)話框相同。

Objective-C版本:

UIAlertAction?*cancelAction?=?[UIAlertAction?actionWithTitle:@"取消"style:UIAlertActionStyleCancel?handler:nil];

UIAlertAction?*deleteAction?=?[UIAlertAction?actionWithTitle:@"刪除"style:UIAlertActionStyleDestructive?handler:nil];

UIAlertAction?*archiveAction?=?[UIAlertAction?actionWithTitle:@"保存"style:UIAlertActionStyleDefault?handler:nil];

[alertController?addAction:cancelAction];

[alertController?addAction:deleteAction];

[alertController?addAction:archiveAction];

swift版本:

var cancelAction?=?UIAlertAction(title:"取消",?style:?UIAlertActionStyle.Cancel,?handler:?nil)

var deleteAction?=?UIAlertAction(title:"刪除",?style:?UIAlertActionStyle.Destructive,?handler:?nil)

var archiveAction?=?UIAlertAction(title:"保存",?style:?UIAlertActionStyle.Default,?handler:?nil)

alertController.addAction(cancelAction)

alertController.addAction(deleteAction)

alertController.addAction(archiveAction)

您不能在上拉菜單中添加文本框,如果您強(qiáng)行添加文本框劲妙,那么就會(huì)得到一個(gè)運(yùn)行時(shí)異常湃鹊。

Objective-C版本:

[self?presentViewController:alertController?animated:YES?completion:nil];

swift版本:

self.presentViewController(alertController,?animated:true,?completion:?nil)

iPhone上的上拉菜單效果

如果上拉菜單中有“取消”按鈕的話,那么它永遠(yuǎn)都會(huì)出現(xiàn)在菜單的底部镣奋,不管添加的次序是如何币呵。

《iOS 用戶界面指南》要求所有的“毀壞”樣式按鈕都必須排名第一。

其他的按鈕將會(huì)按照添加的次序從上往下依次顯示侨颈。

別激動(dòng)得太早余赢,我們現(xiàn)在還有一個(gè)很嚴(yán)重的問(wèn)題,這個(gè)問(wèn)題隱藏得比較深哈垢。當(dāng)我們使用iPad或其他常規(guī)寬度的設(shè)備時(shí)妻柒,就會(huì)得到一個(gè)運(yùn)行時(shí)異常:

Terminating

app due to uncaught exception ‘NSGenericException’, reason:

‘UIPopoverPresentationController

(<_uialertcontrolleractionsheetregularpresentationcontroller:

0x7fc619588110="">) should have a non-nil sourceView or barButtonItem

set before the presentation occurs.’

就如我們之前所說(shuō),在常規(guī)寬度的設(shè)備上耘分,上拉菜單是以彈出框的形式展現(xiàn)举塔。彈出框必須要有一個(gè)能夠作為源視圖或者欄按鈕項(xiàng)目的描點(diǎn)(anchor point)。由于在本例中我們是使用了常規(guī)的UIButton來(lái)觸發(fā)上拉菜單的求泰,因此我們就將其作為描點(diǎn)央渣。在iOS 8中我們不再需要小心翼翼地計(jì)算出彈出框的大小,UIAlertController將會(huì)根據(jù)設(shè)備大小自適應(yīng)彈出框的大小渴频。并且在iPhone或者緊縮寬度的設(shè)備中它將會(huì)返回nil值芽丹。配置該彈出框的代碼如下:

Objective-C版本:

UIPopoverPresentationController類同樣也是在iOS 8中新出現(xiàn)的類,用來(lái)替換UIPopoverController的卜朗。這個(gè)時(shí)候上拉菜單是以一個(gè)固定在源按鈕上的彈出框的形式顯示的拔第。

UIPopoverPresentationController?*popover?=?alertController.popoverPresentationController;

if(popover){

popover.sourceView?=?sender;

popover.sourceRect?=?sender.bounds;

popover.permittedArrowDirections?=?UIPopoverArrowDirectionAny;

}

swift版本:

var popover?=?alertController.popoverPresentationController

if(popover?!=?nil){

popover?.sourceView?=?sender

popover?.sourceRect?=?sender.bounds

popover?.permittedArrowDirections?=?UIPopoverArrowDirection.Any

}

iPad上的上拉菜單效果



要注意UIAlertController在使用彈出框的時(shí)候自動(dòng)移除了取消按鈕。用戶通過(guò)點(diǎn)擊彈出框的外圍部分來(lái)實(shí)現(xiàn)取消操作聊替,因此取消按鈕便不再必需楼肪。

釋放對(duì)話框控制器

通常情況下,當(dāng)用戶選中一個(gè)動(dòng)作后對(duì)話框控制器將會(huì)自行釋放惹悄。不過(guò)您仍然可以在需要的時(shí)候以編程方式釋放它春叫,就像釋放其他視圖控制器一樣。您應(yīng)當(dāng)在應(yīng)用程序轉(zhuǎn)至后臺(tái)運(yùn)行時(shí)移除對(duì)話框或者上拉菜單泣港。假定我們正在監(jiān)聽UIApplicationDidEnterBackgroundNotification通知消息暂殖,我們可以在observer中釋放任何顯示出來(lái)的視圖控制器。(參考在viewDidLoad方法中設(shè)立observer的示例代碼)当纱。

Objective-C版本:

-?(void)didEnterBackground:(NSNotification?*)notification

{

[[NSNotificationCenter?defaultCenter]?removeObserver:self?name:UITextFieldTextDidChangeNotification?object:nil];

[self.presentedViewController?dismissViewControllerAnimated:NO?completion:nil];

}

swift版本:

func?didEnterackground(notification:?NSNotification){

NSNotificationCenter.defaultCenter().removeObserver(self,?name:?UITextFieldTextDidChangeNotification,?object:?nil)

self.presentedViewController?.dismissViewControllerAnimated(false,?completion:?nil)

}

注意呛每,要保證運(yùn)行安全我們同樣要確保移除所有的文本框observer。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末坡氯,一起剝皮案震驚了整個(gè)濱河市晨横,隨后出現(xiàn)的幾起案子洋腮,更是在濱河造成了極大的恐慌,老刑警劉巖手形,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件啥供,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡库糠,警方通過(guò)查閱死者的電腦和手機(jī)伙狐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)瞬欧,“玉大人贷屎,你說(shuō)我怎么就攤上這事∷一ⅲ” “怎么了唉侄?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)顷帖。 經(jīng)常有香客問(wèn)我美旧,道長(zhǎng)渤滞,這世上最難降的妖魔是什么贬墩? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮妄呕,結(jié)果婚禮上陶舞,老公的妹妹穿的比我還像新娘。我一直安慰自己绪励,他們只是感情好肿孵,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著疏魏,像睡著了一般停做。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上大莫,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天蛉腌,我揣著相機(jī)與錄音,去河邊找鬼只厘。 笑死烙丛,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的羔味。 我是一名探鬼主播河咽,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼赋元!你這毒婦竟也來(lái)了忘蟹?” 一聲冷哼從身側(cè)響起飒房,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎媚值,沒(méi)想到半個(gè)月后情屹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡杂腰,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年垃你,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片喂很。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡惜颇,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出少辣,到底是詐尸還是另有隱情凌摄,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布漓帅,位于F島的核電站锨亏,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏忙干。R本人自食惡果不足惜器予,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望捐迫。 院中可真熱鬧乾翔,春花似錦、人聲如沸施戴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)赞哗。三九已至雷则,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間肪笋,已是汗流浹背月劈。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涂乌,地道東北人艺栈。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像湾盒,于是被迫代替她去往敵國(guó)和親湿右。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • iOS 8的新特性之一就是讓接口更有適應(yīng)性罚勾、更靈活毅人,因此許多視圖控制器的實(shí)現(xiàn)方式發(fā)生了巨大的變化吭狡。全新的UIPre...
    烏拉拉zzZ閱讀 932評(píng)論 0 2
  • iOS 8的新特性之一就是讓接口更有適應(yīng)性、更靈活丈莺,因此許多視圖控制器的實(shí)現(xiàn)方式發(fā)生了巨大的變化划煮。全新的UIPre...
    Tank丶Farmer閱讀 2,113評(píng)論 2 4
  • 轉(zhuǎn)載 http://www.cocoachina.com/ios/20141126/10320.html如果侵權(quán),...
    小劉_假裝是個(gè)程序員閱讀 646評(píng)論 0 0
  • 一個(gè)網(wǎng)管的iOS學(xué)習(xí)筆記缔俄,記錄下自己這條路上的點(diǎn)點(diǎn)滴滴弛秋。都是一些很簡(jiǎn)單的筆記,不敢妄談教學(xué)俐载,純粹只是為了記錄自己在...
    degulade閱讀 20,943評(píng)論 4 28
  • 中國(guó)的一個(gè)省相當(dāng)于歐洲的一個(gè)小國(guó) 這是國(guó)人對(duì)自己國(guó)家地大物博的自豪蟹略。是的,我國(guó)一個(gè)省份的面積遏佣、人口挖炬、資源都可以和歐...
    Frank學(xué)習(xí)路上閱讀 675評(píng)論 0 1