UIAlertView,從個人角度來講,認爲蘋果所提供的使用delegate,而將一個對話框的處理拆分爲上下文的方式,並不是一個很好的方案。很多時候,會複雜化程序以及處理邏輯,而一堆的if-else或者switch-case也是很煩人的一件事情。所以,很多開發者對它動手腳。
如果你需要找的是,能夠優美的處理不同的UIAlertView按鍵事件,那麼你可以參考林家男孩的這篇博客。
但是,如果你想找的是模態對話框的功能,你可以參照一下以下的內容。
很多時候,我們只是需要一個模態對話框,讓用戶選擇是或者否,讓代碼繼續下去。去寫上下文分支,真的是個很麻煩的事情,尤其是假如你的應用需要按照某種順序,根據第一個UIAlertView的選擇結果決定彈出第二個甚至更多的UIAlertView。所以,我希望能有個模態的UIAlertView,在我把它show出來之後,它就卡在那兒,直到給我返回一個值,告訴我它點了哪個按鈕。
UIAlertView其實是具備模態功能的,只是蘋果並沒有開放出來,屬於undocumented api,使用它很有可能被拒於AppStore之外。
它的私有API是這個:-[UIAlertView(Private) setRunsModal:]
怎麼使用這個API我就不介紹了,大家可以上網查。事實上,在iPhone剛出來的時候,大家還是很經常使用這個API的。
這兒我要介紹的是另一種使用方法。
要想實現UIAlertView的模態效果,其實是比較簡單的,無非是讓它被show之後,代碼能夠停留在那空轉,直到它被點擊。
需要空轉的時候,就是NSRunLoop/CFRunLoop出場的時候了。NSRunLoop/CFRunLoop的作用,請參考官方文檔。很多時候我們都要用到它,尤其是在線程中使用網絡和定時器的時候。
底下簡單列出我的解決方案:
- @interface MyModalAlertView : UIAlertView
- - (int)showModal;
- @end
- #import "MyModalAlertView.h"
- @implementation NdGHModalAlertView
- - (int)showModal
- {
- self.delegate = self;
- self.tag = -1;
- [self show];
- CFRunLoopRun();
- return self.tag;
- }
- - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
- {
- alertView.tag = buttonIndex;
- alertView.delegate = nil;
- CFRunLoopStop(CFRunLoopGetCurrent());
- }
- @end
其實它的實現思路很簡單,就是在show之後,讓代碼空轉,然後在點擊按鈕之後,停止空轉,並返回按鍵值。
所以,使用上述代碼,你可以獲得一個簡單的模態對話框,用UIAlertView一樣的初始化方法,調用自定義的showModal,而不是系統的show,通過返回值來確定它所按下的按鍵。
後記:
其實這個類兩年前就寫好了,一直沒有決定放入項目使用,直到今年,終於受不了了,把它加入了工程。