模態UIAlertView

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的作用,請參考官方文檔。很多時候我們都要用到它,尤其是在線程中使用網絡和定時器的時候。

底下簡單列出我的解決方案:

 

  1. @interface MyModalAlertView : UIAlertView 
  2.  
  3. - (int)showModal; 
  4.  
  5. @end 

 

  1. #import "MyModalAlertView.h" 
  2.  
  3. @implementation NdGHModalAlertView 
  4.  
  5. - (int)showModal 
  6.     self.delegate = self; 
  7.     self.tag = -1; 
  8.     [self show]; 
  9.     CFRunLoopRun(); 
  10.     return self.tag; 
  11.  
  12. - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex 
  13.     alertView.tag = buttonIndex
  14.     alertView.delegate = nil
  15.     CFRunLoopStop(CFRunLoopGetCurrent()); 
  16.  
  17. @end 

其實它的實現思路很簡單,就是在show之後,讓代碼空轉,然後在點擊按鈕之後,停止空轉,並返回按鍵值。

所以,使用上述代碼,你可以獲得一個簡單的模態對話框,用UIAlertView一樣的初始化方法,調用自定義的showModal,而不是系統的show,通過返回值來確定它所按下的按鍵。

 

後記:

其實這個類兩年前就寫好了,一直沒有決定放入項目使用,直到今年,終於受不了了,把它加入了工程。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章