iOS 8 中的 AlertView 问题

Posted

技术标签:

【中文标题】iOS 8 中的 AlertView 问题【英文标题】:AlertView issue in iOS 8 【发布时间】:2015-09-21 05:27:13 【问题描述】:

我在 AlertView 中添加了一个 UIVIew,如下所示:

UIView *alertSubView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 260, 55)];
        [alertSubView addSubview:textField];
        [alertSubView addSubview:charLeftLabel];

        [alert setValue:alertSubView forKey:@"accessoryView"];

问题

UIView* alertSubView = [alertView valueForKey:@"accessoryView"];

当我尝试在 Alertview 委托方法中获取该子视图时,应用程序崩溃。

它在 iOS7 中运行良好,但仅在 iOS 8 中存在问题

错误由于未捕获的异常“NSUnknownKeyException”而终止应用程序,原因:“[valueForUndefinedKey:]:该类不符合键附件视图的键值编码。

【问题讨论】:

@Fonix,它在 ios 7 中运行良好,但只有 iOS 8 存在问题 您需要使用自定义警报视图而不是这样做:检查github.com/wimagguc/ios-custom-alertview 当您针对该键设置警报值时,您正尝试访问 alertView 的值 【参考方案1】:

警报视图已弃用。您应该使用UIAlertController。这只是一个建议。

例如作为你的方面:

UIAlertController *alertController = [UIAlertController
                                      alertControllerWithTitle:@"Alert Controller"
                                      message:@"Alert Message"
                                      preferredStyle:UIAlertControllerStyleAlert];

UIViewController *viewController = [[UIViewController alloc]init];
[viewController.view setBackgroundColor:[UIColor blueColor]];

UILabel *lbl = [[UILabel alloc]initWithFrame:CGRectMake(10, 8, 250, 30)];
lbl.text = @"This is a label";
lbl.textAlignment = NSTextAlignmentCenter;
lbl.textColor = [UIColor whiteColor];
[viewController.view addSubview:lbl];

UITextField *tf = [[UITextField alloc]initWithFrame:CGRectMake(10, 35, 250, 30)];
tf.borderStyle = UITextBorderStyleRoundedRect;
tf.placeholder = @"Enter your name";
[viewController.view addSubview:tf];

[alertController setValue:viewController forKey:@"contentViewController"];

UIAlertAction *cancelAction = [UIAlertAction
                               actionWithTitle:@"Cancel"
                               style:UIAlertActionStyleCancel
                               handler:^(UIAlertAction *action)
                               
                                   NSLog(@"Cancel action");
                               ];

UIAlertAction *okAction = [UIAlertAction
                           actionWithTitle:@"OK"
                           style:UIAlertActionStyleDefault
                           handler:^(UIAlertAction *action)
                           
                               NSLog(@"OK action");

                               NSLog(@"Text Value : %@",tf.text);
                           ];

[alertController addAction:cancelAction];
[alertController addAction:okAction];

dispatch_async(dispatch_get_main_queue(), ^
    [self presentViewController:alertController animated:YES completion:nil];
);

希望对你有帮助。

【讨论】:

【参考方案2】:

你可以在 swift 2.0 中做同样的事情,就像下面的代码:

let alert = UIAlertController(title: "Alert Controller", message: "Alert Message", preferredStyle: UIAlertControllerStyle.Alert)


let cancelAction = UIAlertAction(
    title: "Cancel",
    style: UIAlertActionStyle.Destructive)  (action) in



let confirmAction = UIAlertAction(
    title: "OK", style: UIAlertActionStyle.Default)  (action) in



alert.addAction(confirmAction)
alert.addAction(cancelAction)

let VC = UIViewController()
VC.view.backgroundColor = UIColor.blackColor()


let lbl =  UILabel()
lbl.frame =  CGRectMake(10, 8, 250, 30)
lbl.text = "this is a label"
lbl.textAlignment = NSTextAlignment.Center
lbl.textColor = UIColor.whiteColor()
VC.view .addSubview(lbl)


let txt = UITextField()
txt.frame =  CGRectMake(10, 35, 250, 30)
txt.borderStyle = UITextBorderStyle.RoundedRect
txt.placeholder = "enter text"
VC.view .addSubview(txt)


alert.setValue(VC, forKey: "contentViewController")

self.presentViewController(alert, animated: true, completion: nil)

从 Github 下载 Demo:https://github.com/nitingohel/NGAlertViewController-Swift2.0

【讨论】:

【参考方案3】:

试试这个代码:

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"TEST" message:@"subview" delegate:nil cancelButtonTitle:@"NO" otherButtonTitles:@"YES", nil];
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 260, 55)];
[view addSubview:textField];
[view addSubview:charLeftLabel];
[alert setValue:view forKey:@"accessoryView"];
[alert show];

【讨论】:

感谢您的回复!但我需要为警报视图调用委托方法。 @user2526811 -- 你需要哪种委托方法【参考方案4】:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"TEST" message:@"subview" delegate:self cancelButtonTitle:@"NO" otherButtonTitles:@"YES", nil];
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 260, 55)];
[view addSubview:textField];
[view addSubview:charLeftLabel];
[alert setValue:view forKey:@"accessoryView"];
[alert show];

【讨论】:

在上面给delegate:self 然后我们只调用alertview 委托方法 您必须将委托设置为警报视图,然后才能使用按钮单击并且您尚未将委托设置为警报视图 我已经设置了委托,这就是为什么要调用委托方法。 请仔细阅读我的问题并查看其他答案。 在其他代码中他们给了 delegate=nil 这就是为什么建议你。

以上是关于iOS 8 中的 AlertView 问题的主要内容,如果未能解决你的问题,请参考以下文章

iOS 7 和 iOS 8 中的警报视图与 UIAlertController

在 iOS 8.1 之后,在所有设备上,当点击 alertview 取消按钮时,ScrollView 向上并且不滚动

alertview 中的图像在 ios7 中不起作用

关于 iOS7 中的 AlertView App Crash

转载通用iOS AlertView设计与实现

在 iOS 8.3 for iPad 上关闭 UIAlertView 后键盘弹出