自定义警报视图的验证

时间:2014-04-16 12:58:21

标签: ios objective-c ios7 uiviewcontroller uialertview

我已在警报视图中添加了自定义视图。

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

虽然点击了警报视图中的任何按钮,但未调用此方法。 Apple说,

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 个答案:

答案 0 :(得分:2)

我的建议是用其他内容替换UIAlertViewTTAlertViewSDCAlertView都在积极开发中,应该允许您灵活地以任何方式对视图进行子类化和/或设置。

答案 1 :(得分:0)

我同意其他人的意见,您应该考虑创建自己的警报视图替换。这里说的是一些使用UIAlertView的选项。

1)不要使用原生UIAlertView按钮(取消/提交)。而是将您自己的按钮合并到附件视图中,并在没有任何按钮的情况下配置UIAlertView本身。现在你完全掌控了。但是您的按钮看起来与原生警报视图按钮不完全相同,因为您无法将它们放置在正确的位置。

2)点击提交按钮后,您可以尝试禁用提交按钮,直到整个表单验证为止,而不是验证用户的输入。也就是说,保持提交按钮被禁用,直到它通过验证。问题是UIAlertView中禁用/启用提交按钮的功能非常有限。如果您使用UIAlertView的原生UIAlertViewPlainTextInputStyle,请注意您可以通过委托回调alertViewShouldEnableFirstOtherButton:启用/停用提交按钮。

我能够在附件视图中使用我自己的UITextField(使用UIAlertViewDefaultStyle时)来构建此行为并启用/禁用提交按钮。有一个非常好的论据是不使用这种技术,因为它使用无证机制非常边缘。 (好吧,它几乎就行了......)。但这是我的解决方案,为了完整性:

注意,TSAlertViewFormController UIViewController的观点被用作accessoryView的{​​{1}}。您需要确保视图控制器本身(不仅仅是其视图)保持活动的持续时间与包含它的UIAlertView相同。此外,您需要在其上设置弱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