日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

iOS (封装)一句话调用系统的alertView和alertController

發(fā)布時間:2025/3/15 windows 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iOS (封装)一句话调用系统的alertView和alertController 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言:

本文僅作參考存留,請用新版封裝:iOS 更加優(yōu)雅便捷的UIAlertView/UIAlertController封裝使用

UIAlertController是iOS8.0之后出來的新方法,其將系統(tǒng)原先的UIAlertView和UIActionSheet進行了規(guī)范整合。iOS9.0之后,UIAlertView和UIActionSheet已經(jīng)不建議使用,但還未徹底廢棄。
alert提示窗可以算得上是十分常用的UI控件了,基于上述情況,考慮到版本兼容,筆者將上述控件進行了簡單的整合封裝。
封裝之后,只需一句話,便可調(diào)用系統(tǒng)的alert提示,至于是調(diào)用alertView還是alertController,會根據(jù)系統(tǒng)版本自行判斷,做到了兼容適配。alert提示窗的回調(diào)方法,也基于block進行了封裝。按鈕數(shù)量提供了變參和數(shù)組兩種封裝模式,各有用途。

代碼見GitHub,已將這個較為簡單但個人感覺還算十分實用的庫進行了開源共享,喜歡的歡迎下載使用。
代碼可能還入不了大牛的眼,水平有限,還望見諒,也歡迎使用和反饋。

支持的多種效果展示


下面敘述一下封裝庫內(nèi)部分主要API的具體說明,代碼中也有較為詳細的注釋。

1.普通alert 變參 兼容適配alertView和alertController

/*** 普通alert定義 兼容適配alertView和alertController** @param viewController 當(dāng)前視圖,alertController模態(tài)彈出的指針* @param title 標題* @param message 詳細信息* @param block 用于執(zhí)行方法的回調(diào)block* @param cancelBtnTitle 取消按鈕,可為nil* @param destructiveBtn alertController的特殊按鈕類型,可為nil* @param otherButtonTitles 其他按鈕 變參量 但是按鈕類型的相對位置是固定的,可為nil * NS_REQUIRES_NIL_TERMINATION 是一個宏,用于編譯時非nil結(jié)尾的檢查 自動添加結(jié)尾的nil ***注意1*** //block方法序列號和按鈕名稱相同,按鈕類型排列順序固定 //如果取消為nil,則index0為特殊,以此往后類推,以第一個有效按鈕為0開始累加 //取消有的話默認為0 ***注意2*** destructiveButtonTitle iOS8以前,alert設(shè)置無效,因為不支持 iOS8以后,alert設(shè)置有效 */ + (void) showAlertWith:(UIViewController *)viewController title:(NSString *)title message:(NSString *)message callbackBlock:(CallBackBlock)block cancelButtonTitle:(NSString *)cancelBtnTitle destructiveButtonTitle:(NSString *)destructiveBtn otherButtonTitles:(NSString *)otherButtonTitles, ...NS_REQUIRES_NIL_TERMINATION;

具體調(diào)用實例(默認系統(tǒng)是ios8以后的):

[JXTAlertTools showAlertWith:self title:EmptyTitle message:_titleArray[indexPath.row] callbackBlock:^(NSInteger btnIndex) {if (btnIndex == 0) {NSLog(@"取消"); } if (btnIndex == 1) {//注意ios8以前,沒有這個鍵 NSLog(@"特殊"); } if (btnIndex == 2) { NSLog(@"其他"); } } cancelButtonTitle:@"取消" destructiveButtonTitle:@"特殊" otherButtonTitles:@"其他", nil];

沒有按鈕時:

//沒有按鈕時,默認自動消失[JXTAlertTools showAlertWith:self title:EmptyTitle message:_titleArray[indexPath.row] callbackBlock:nil cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil, nil];

彈窗自動消失的持續(xù)時間由宏控制,可自行修改(詳見JXTAlertTools.h):

/*** 彈框顯示的時間,默認1秒*/#define AlertViewShowTime 1.0

2.多按鈕數(shù)組模式排布alert 兼容適配alertView和alertController

/*** 多按鈕列表數(shù)組排布alert初始化 兼容適配** @param viewController 當(dāng)前視圖,alertController模態(tài)彈出的指針* @param title 標題* @param message 詳細信息* @param block 用于執(zhí)行方法的回調(diào)block * @param cancelBtnTitle 取消按鈕 * @param otherBtnTitleArray 其他按鈕的標題數(shù)組 * @param otherBtnStyleArray 按鈕樣式分布數(shù)組(普通/特殊),alertView默認為普通樣式 ***注意*** UIAlertActionStyleCancel/JXTAlertActionStyleCancel最多只能有一個,否則崩潰 Log: 'UIAlertController can only have one action with a style of UIAlertActionStyleCancel' */ + (void)showArrayAlertWith:(UIViewController *)viewController title:(NSString *)title message:(NSString *)message callbackBlock:(CallBackBlock)block cancelButtonTitle:(NSString *)cancelBtnTitle otherButtonTitleArray:(NSArray *)otherBtnTitleArray otherButtonStyleArray:(NSArray *)otherBtnStyleArray;

此方法是為了彌補前面那個方法初始化時,alert的按鈕樣式排布相對固定的局限,當(dāng)然,這種排布只在iOS8之后有效。

具體調(diào)用實例(默認系統(tǒng)是ios8以后的):

NSArray * titles = @[@"確定1", @"特殊1", @"確定2", @"特殊2"]; NSArray * styles = @[ [NSNumber numberWithInteger:JXTAlertActionStyleDefault], [NSNumber numberWithInteger:JXTAlertActionStyleDestructive], [NSNumber numberWithInteger:JXTAlertActionStyleDefault], [NSNumber numberWithInteger:JXTAlertActionStyleDestructive] ]; [JXTAlertTools showArrayAlertWith:self title:EmptyTitle message:_titleArray[indexPath.row] callbackBlock:^(NSInteger btnIndex) { if (btnIndex == 0) { NSLog(@"取消"); } else NSLog(@"%@", titles[btnIndex - 1]); } cancelButtonTitle:@"取消" otherButtonTitleArray:titles otherButtonStyleArray:styles];

上面要注意按鈕的樣式是枚舉值,添加數(shù)組時要注意轉(zhuǎn)化為對象,這里用了NSNumber,因為方法實現(xiàn)中也是按照NSNumber解析的:

NSNumber * styleNum = otherBtnStyleArray[i];UIAlertActionStyle actionStyle = styleNum.integerValue;UIAlertAction *otherAction = [UIAlertAction actionWithTitle:otherBtnTitleArray[i] style:actionStyle handler:^(UIAlertAction *action) { block(count); }]; [alertController addAction:otherAction];

樣式枚舉定義:

typedef enum {JXTAlertActionStyleDefault = 0,JXTAlertActionStyleCancel,JXTAlertActionStyleDestructive}JXTAlertActionStyle;

這里之所以不用系統(tǒng)提供的:

typedef NS_ENUM(NSInteger, UIAlertActionStyle) {UIAlertActionStyleDefault = 0,UIAlertActionStyleCancel, UIAlertActionStyleDestructive } NS_ENUM_AVAILABLE_IOS(8_0);

是因為為了系統(tǒng)版本適配,系統(tǒng)的樣式枚舉是iOS8之后才提供的,如果直接使用,系統(tǒng)版本一旦低于iOS8,此時使用可能導(dǎo)致程序崩潰。

沒有按鈕時,情況同上:

[JXTAlertTools showArrayAlertWith:self title:EmptyTitle message:_titleArray[indexPath.row] callbackBlock:nil cancelButtonTitle:nil otherButtonTitleArray:nil otherButtonStyleArray:nil];

關(guān)于actionSheet的API,基本同上,也提供了兩個相應(yīng)的方法,同樣是兼容適配的。
關(guān)于方法的具體實現(xiàn),在此不再贅述,有興趣的可以參考代碼,有什么問題歡迎討論。

3.兩種簡易提示窗

這兩種建議的提示窗,是基于上述方法的簡化,適用于較為簡單的提示場景。

  • 1.單按鈕或無按鈕alert提示

    [JXTAlertTools showTipAlertViewWith:self title:EmptyTitle message:_titleArray[indexPath.row] buttonTitle:@"確認" buttonStyle:JXTAlertActionStyleDefault];
  • 2.窗口底部簡易actionSheet,無按鈕

    [JXTAlertTools showBottomTipViewWith:self title:_titleArray[indexPath.row] message:_titleArray[indexPath.row]];

4.兩個特殊用途的方法

  • 1.判斷當(dāng)前窗口是否有alert/actionSheet顯示 + (BOOL)isAlertShowNow; 這個的用途具體看需求,可以用來去重顯示,尤其是在alertView的情況下,有時可能連續(xù)多次彈出同一alertView,例如觀察者回調(diào),系統(tǒng)貌似沒有做去重處理,筆者就遇到過監(jiān)聽回調(diào)導(dǎo)致的alert重復(fù)顯示。但是如果是alertController,就不會發(fā)生了,控制臺可能會直接給出警告的,因為是試圖在一個已經(jīng)銷毀的vc上(第一次彈出的alertController消失時)第二次連續(xù)推出視圖,這是做不到的。
    做去重顯示判定時,此方法慎用,因為未做彈窗區(qū)分,同時的彈窗有可能是因為重復(fù)顯示,也可能是不同警告類型的提示窗,去重的話就可能導(dǎo)致第二個不同的提示窗被過濾掉。

用法示例:

NSLog(@"顯示alert:%@", [JXTAlertTools isAlertShowNow] ? @"是" : @"否");if (![JXTAlertTools isAlertShowNow]) {//檢測彈窗,控制alertView的去重顯示[JXTAlertTools showTipAlertViewWith:self title:EmptyTitle message:_titleArray[indexPath.row] buttonTitle:nil buttonStyle:JXTAlertActionStyleDefault]; } NSLog(@"顯示alert:%@", [JXTAlertTools isAlertShowNow] ? @"是" : @"否");

控制臺輸出:


可能用方法有問題,但我是臨時這個解決的。。。

  • 2.查找當(dāng)前活動窗口 + (UIViewController *)activityViewController;

這個方法源于網(wǎng)絡(luò),實際使用可行,主要是用來確定alertController的,也就是上面那個方法有用到此方法(已封裝),當(dāng)然這個方法不局限于只確定alertController。而且,alertView的檢測和alertController的檢測不是同一個方法,畢竟一個是view,一個是vc。

5.封裝時遇到的一個小問題

當(dāng)且僅當(dāng)模擬器使用6p或者6sp時,alert有至多2個按鈕,至少1個按鈕,alert的message中使用“\n”時,分為3行,第一行無所謂,第2行字符小于38字符或者第3行字符小于76時(\n算一個字符,數(shù)字可能記錯了。。。),控制臺直接給了下面的警告,警告的達成條件較為苛刻,2、3任意一行多于臨界值都不行,但的確是偶然,同樣的字符數(shù),沒有“\n”就沒事,多于這幾個臨界值也沒事,唯獨不能少。。。:

最簡單的一個messge實例:@“1\n2\n3”

警告:

2016-01-28 10:13:47.714 JXTAlertTools[2379:60409] the behavior of the UICollectionViewFlowLayout is not defined because:
2016-01-28 10:13:47.715 JXTAlertTools[2379:60409] the item height must be less than the height of the UICollectionView minus the section insets top and bottom values, minus the content insets top and bottom values.
2016-01-28 10:13:47.715 JXTAlertTools[2379:60409] The relevant UICollectionViewFlowLayout instance is <_UIAlertControllerCollectionViewFlowLayout: 0x7fc21ac7ed10>, and it is attached to <UICollectionView: 0x7fc21c877a00; frame = (0 94.6667; 270 44); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x7fc21ac1b5d0>; layer = <CALayer: 0x7fc21ac1c470>; contentOffset: {0, 0}; contentSize: {0, 0}> collection view layout: <_UIAlertControllerCollectionViewFlowLayout: 0x7fc21ac7ed10>.
2016-01-28 10:13:47.715 JXTAlertTools[2379:60409] Make a symbolic breakpoint at UICollectionViewFlowLayoutBreakForInvalidSizes to catch this in the debugger.

不是無聊,只是偶然碰到這個情況,當(dāng)時還排查了半天,最后才發(fā)現(xiàn)是這個問題,這也是很容易遇到的問題,無論是alertView還是alertController,都會出現(xiàn)。

復(fù)制代碼:

UIAlertView * al = [[UIAlertView alloc] initWithTitle:@"title" message:@"1\n2\n2" delegate:self cancelButtonTitle:@"ok" otherButtonTitles:nil, nil]; [al show];

或者:

UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"title" message:@"1\n2\n2" preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction * act =[UIAlertAction actionWithTitle:@"ok" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { NSLog(@"輸出"); }]; [alert addAction:act]; [self presentViewController:alert animated:YES completion:nil];

用6p或者6sp運行,就會出現(xiàn)上述警告,原因不明(系統(tǒng)bug?)。。。其他模擬器都沒事。這里提出來只是提醒注意規(guī)避吧。

而且分析上述警告也很有意思,大致是說UICollectionView的布局有問題,這是不是可以說明系統(tǒng)的alertView或者alertController都是利用UICollectionView進行封裝的呢?

上述臨界情況的樣式:
1.不會出現(xiàn)的:



2.會出現(xiàn)的,僅僅是少了一個字符:


參考文章:
1.iOS 引用當(dāng)前顯示的UIAlertView
2.IOS -獲取當(dāng)前視圖的Controller
3.UIWindowLevel詳解

·轉(zhuǎn)載請聲明出處·

轉(zhuǎn)載于:https://www.cnblogs.com/Free-Thinker/p/7080879.html

總結(jié)

以上是生活随笔為你收集整理的iOS (封装)一句话调用系统的alertView和alertController的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。