2014-04-16 84 views
0

我已將自定義視圖添加到警報視圖。驗證自定義警報視圖

MyViewController *myViewController = [self.storyboard instantiateViewControllerWithIdentifier: @"MyView"]; 
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:nil delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Submit", nil];                           
[alertView setValue: myViewController.view forKey:@"accessoryView"];    
[alertView show]; 

myViewController.view中有幾個文本框。警報視圖有兩個按鈕「提交」和「取消」。

enter image description here

輕敲「提交」按鈕,我需要在文本框來驗證輸入。如果輸入無效,我不想解除警報。例如。如果電子郵件無效,我會顯示另一個提示「電子郵件無效」。我該如何實現這個目標?在下面的方法

1)編寫驗證邏輯:我嘗試下面的事情到目前爲止

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex; 

但警報視圖下執行此方法後解散。

2)繼承UIAlertView。我試圖重寫以下方法在子類UIAlertView中:雖然我點擊任何關於警報視圖按鈕

- (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated 

這種方法不會被調用。蘋果說,

The UIAlertView class is intended to be used as-is and does not support subclassing. The view hierarchy for this class is private and must not be modified. 

我已經花了很多時間今天解決這個問題,但沒有運氣..!請幫幫我。

+2

剛剛創建自己的AlertView,因爲alertview僅被用作是。您正在使用私人方法來設置您的自定義視圖,這可能會讓您的應用遭到拒絕。 – rckoenes

+0

感謝您的建議@ rckoenes ..! –

+0

我想你可以使用委託方法的東西。 (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex; – BangOperator

回答

2

我的建議是用UIAlertView替換別的東西。 TTAlertViewSDCAlertView都處於積極的發展階段,並且應該允許您靈活地按照您需要的方式對視圖進行分類和/或蒙皮。

0

我同意他人,你應該考慮創建自己的警報視圖替換。這就是說這裏有幾個選項使用UIAlertView

1)不要使用原生UIAlertView按鈕(取消/提交)。相反,將您自己的按鈕合併到您的配件視圖中,並配置UIAlertView本身,而無需任何按鈕。現在你完全可以控制。但是你的按鈕看起來不像本機警報視圖按鈕,因爲你不能將它們放置在正確的位置。

2)點擊提交按鈕後,您可以嘗試禁用提交按鈕,直到表單整體驗證爲止,而不是驗證用戶的輸入。也就是說,保持提交按鈕被禁用,直到它通過驗證。問題在於UIAlertView禁用/啓用提交按鈕的能力非常有限。如果您使用UIAlertView的原生UIAlertViewPlainTextInputStyle,您會注意到您可以通過代理回調alertViewShouldEnableFirstOtherButton:啓用/禁用提交按鈕。

我能夠建立這種行爲,並啓用/禁用基於附件視圖中我自己的UITextField提交按鈕(同時使用UIAlertViewDefaultStyle)。有一個非常好的理由,不要使用這種技術,因爲它使用無證的機制是非常接近的。 (好吧,這幾乎是......)。但這裏是我的解決方案,爲完整性:

注意,TSAlertViewFormControllerUIViewController誰的觀點是作爲UIAlertViewaccessoryView。您需要確保視圖控制器本身(不僅僅是其視圖)保持活動狀態的時間與包含它的UIAlertView相同。此外,你需要設置它的弱alertView屬性!

@interface TSAlertViewFormController() <UIAlertViewDelegate> 
@end 

@implementation TSAlertViewFormController 
{ 
    IBOutlet UITextField* _textField; 
} 

- (BOOL) alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView; 
{ 
    // validate all your fields here! 

    return [_textField.text isEqualToString: @"abc"]; 
} 

- (void) setAlertView:(UIAlertView *)alertViewHost 
{ 
    [self view]; 

    _alertView = alertViewHost; 

    // sniff out the selector used to handle textfield editing events 
    // this could (should!) be considered "undocumented" behavior 
    // (one major issue is we assume the target is the UIAlertView itself!) 
    UIAlertView* avtemp = [UIAlertView new]; 
    avtemp.alertViewStyle = UIAlertViewStylePlainTextInput; 
    UIControl* avtempTextField = [avtemp textFieldAtIndex: 0]; 

    NSArray* actions = [avtempTextField actionsForTarget: avtemp forControlEvent: UIControlEventEditingChanged]; 
    if (actions.count > 0) 
    { 
     SEL action = NSSelectorFromString(actions.lastObject); 

     // route our text field editing-changed events to the host alert view 
     // do this for each textfield! 
     [_textField addTarget: self.alertView action: action forControlEvents: UIControlEventEditingChanged]; 
    } 
    else 
    { 
     // need to fail gracefully here... 
    } 
} 

@end 

這裏是如何使用它:

@implementation TSViewController 
{ 
    TSAlertViewFormController* _avc; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    _avc = [self.storyboard instantiateViewControllerWithIdentifier: @"avc"]; 
    _avc.view.frame = CGRectMake(0, 0, 200, 300); 

    UIAlertView* av = [[UIAlertView alloc] initWithTitle: nil 
               message: nil 
               delegate: _avc 
             cancelButtonTitle: @"Cancel" 
             otherButtonTitles: @"Submit", nil]; 

    _avc.alertView = av; 

    [av setValue: _avc.view forKey: @"accessoryView"]; 
    [av show]; 
}