2011-11-29 83 views
1

我試圖對UIAlertView進行子類化,以更好地處理我的應用中的錯誤狀態。麻煩時遇到與otherButtonTitles無終止的參數,當我創建我的子類,它只是拿起在列表中的第一個字符串,而不是所有的字符串UIAlertView的子類化

+ (ErrorAlertView *)displayErrorAlertViewWithTitle:(NSString *)title 
              message:(NSString *)message 
              delegate:(id<UIAlertViewDelegate>)delegate 
            errorDelegate:(id<ErrorAlertViewDelegate>)errorDelegate 
           cancelButtonTitle:(NSString *)cancelButtonTitle 
             displayNow:(BOOL)displayNow 
               tag:(NSUInteger)tag 
           otherButtonTitles:(NSString *)otherButtonTitles, ...; 

{ 

    ErrorAlertView *errorAlertView = [[ErrorAlertView alloc] initWithTitle:title 
                    message:message 
                   delegate:delegate 
                 cancelButtonTitle:cancelButtonTitle 
                 otherButtonTitles:otherButtonTitles, nil]; 


    errorAlertView.errorDelegate = errorDelegate; 
    errorAlertView.tag = tag; 

    if (displayNow) { 

    [errorAlertView show]; 

    } 

    return [errorAlertView autorelease]; 


} 

如果我提出以下撥打以上方法:

[ErrorAlertView displayErrorAlertViewWithTitle:[self noInternetConnectionAlertViewTitle] 
              message:[self noInternetConnectionAlertViewMessage] 
              delegate:self 
            errorDelegate:errorDelegate 
           cancelButtonTitle:@"OK" 
             displayNow:YES 
               tag:ErrorAlertTagInternetConnectionError 
           @"Try again",@"Setting", nil]; 

顯示的UIAlertView只顯示@「Try again」按鈕。

+1

[目的-C繞過...零終止參數列表(可能重複http://stackoverflow.com/questions/2345196/objective-c-passing-around-nil-終止參數列表) –

回答

4

您不能發送一組變量參數。

當我子類UIAlertView中我這樣做:

va_list args; 
va_start(args, otherButtonTitles); 
for (NSString *anOtherButtonTitle = otherButtonTitles; anOtherButtonTitle != nil; anOtherButtonTitle = va_arg(args, NSString*)) { 
    [self addButtonWithTitle:anOtherButtonTitle]; 
} 

或者,你可以創建你的函數的一個變種,它接受的va_list的(單)參數,然後運行上面的代碼。

一般來說,在編寫可變參數函數時,應該包含處理這種可能性的替代方法。在這種情況下,Apple提供addButtonWithTitle:方法。

+1

謝謝,完美的作品 – williamb

14

UIAlertView Class Reference

子類票據

的UIAlertView中類旨在被原樣使用,並且不支持 子類。該類的視圖層次結構是私有的,並且不得修改 。

但是,還有許多其他警報視圖實現,您可能會發現有用,發佈here on CocoaControls

+2

它可以由於各種原因而安全地進行分類,例如創建自動解僱時進入後臺狀態版本。 – tarmes

+3

從隨機觀察中推斷出,如果Apple文檔*明確指出某些東西不會被子類化,那麼子類就是安全的,這是一個非常糟糕的主意。他們可能有內部緩存或使用其他技術,以微妙的方式破壞或損壞記憶。即使它現在起作用,蘋果公司可能會稍後改變課程,因爲畢竟它被記錄爲非子類。開發者可能會保留這一點,直到有時間實現特定的新功能或優化或錯誤修復。 – uliwitness

+1

@Suragch更新,謝謝。 – Luke

1

而不是UIAlertView的子類,我更喜歡創建簡單的類,通常只有一個show方法需要一個委託參數。委託協議則具有與可用選項相對應的表達方法。

雖然這種方法導致比典型的警報視圖委託方法更多的委託功能,但我認爲它使代碼更具可讀性。

的代碼通常看起來像這樣(SWIFT):

@objc protocol DeleteUniverseAlertViewDelegate { 
    func deleteUniverseAlertViewDidConfirmDelete(view: DeleteUniverseAlertView) 
} 


class DeleteUniverseAlertView : NSObject, UIAlertViewDelegate { 

    private weak var delegate: DeleteUniverseAlertViewDelegate? = nil 

    class func showWithDelegate(delegate: DeleteUniverseAlertViewDelegate) -> DeleteUniverseAlertView { 
     let view = DeleteUniverseAlertView() 
     view.delegate = delegate 
     UIAlertView(title: "Delete universe?", message: "Are you really, really sure about this?", delegate: view, cancelButtonTitle: "Cancel", otherButtonTitles: "Yes, delete!").show() 
     return view 
    } 

    func alertView(alertView: UIAlertView, clickedButtonAtIndex buttonIndex: Int) { 
     if (buttonIndex > 0) { 
      delegate?.deleteUniverseAlertViewDidConfirmDelete(self) 
     } 
    } 
} 

當你再需要出示此警報,只實現了協議,並顯示類似這樣的定製警報(記得要保持一個強大的參考警報視圖):

deleteAlert = DeletePlaceAlertView.showWithDelegate(self)