在iOS 8中自定义UIAlertController以包括UITableView等标准元素

17

我习惯通过 [alert setValue:someView forKey:@"accessoryView"]] 方法自定义 UIAlertViews。这为 UIAlertViews 带来了可定制的内容和自定义高度。然而,它只适用于 iOS7 及以下版本。在 iOS8 中,UIAlertController 已经代替了它,我无法再自定义它,否则将会缩小 UIAlertView 的高度。

是因为误用 UIAlertController 所以不可能实现,还是我应该怎样做呢? 我正在尝试在 UIAlertControllerStyleAlert 内嵌入一个 UITableView 。

谢谢。


我最终使用了这个库 https://github.com/wimagguc/ios-custom-alertview,放弃了UIAlertController。 - kbjeppesen
4个回答

36

我现在遇到了同样的问题。我查看了UIAlertController的私有头文件(https://github.com/nst/iOS-Runtime-Headers/blob/master/Frameworks/UIKit.framework/UIAlertController.h),发现了一个有希望的属性:contentViewController

结果发现它与UIAlertView以前使用的accessoryView完全相同,唯一的区别是您需要将UIViewController分配给此属性,而不是UIView。

UIViewController *v = [[UIViewController alloc] init];
v.view.backgroundColor = [UIColor redColor];

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

那段代码将在警告视图上显示一个红色视图!快乐地自定义UIAlertController ;)

PS. 这是一个私有属性,但使用KVC在App Store方面不应该有问题,我想。

编辑:

一些人抱怨说这不太安全。它不是公共API,所以是的,苹果可能在任何发布版本中更改它,导致此方法失败。

为了确保如果发生更改整个应用程序都不会崩溃,您可以将KVC调用包装在try块中。如果属性更改,则您的控制器不会显示内容视图,但它也不会崩溃:

@try {
    [alertController setValue:v forKey:@"contentViewController"];
}
@catch(NSException *exception) {
    NSLog(@"Failed setting content view controller: %@", exception);
}

在生产中使用这种方法可能存在风险,我不建议将其用于重要警报。


1
你可以重写-preferredContentSize方法,在你设置为contentViewController的视图控制器中返回自定义尺寸。 - JonasG
1
就像我在答案中所说的那样,因为你是通过KVO进行赋值,所以它不会被苹果的静态分析器检测到,因此它将通过审核过程。 - JonasG
11
几年前,我们使用 KVO 访问 UIAlertView 上的“_buttons”时做了类似的事情。然后他们更改了标识符的名称,所有的 IAP 都在 iOS 8 上停止工作了。为 20 个应用程序匆忙修复问题的几天不好过。我强烈建议不要使用这种解决方案。 - James Webster
3
你强烈建议使用什么替代方案? - Alex Sorokoletov
1
我建议不要费力地将此功能塞入本机警报中。许多人已经复制了本机警报,制作出几乎完美的副本,处理了所有旋转/大小/交互边缘情况。我已经成功地使用SDCAlertView @ https://github.com/sberrevoets/SDCAlertView。 - Adam Kaplan
显示剩余12条评论

12

我建议不要浪费时间试图把额外的UI挤入不应该存在的地方。根据过去几年的改进,苹果可能会在下一个iOS版本中添加自定义视图。在那之前,可以看看一个专门处理这种情况而不违反任何最佳实践的框架:SDCAlertView

它支持模拟iOS 7、8、9上的原生警报,包括处理所有关于大小、按钮类型、旋转等令人困扰的边缘情况。它确实支持在警报内部使用任意自定义视图。

SDCAlertView演示gif

我在雅虎YMPromptKit中使用这个库来制作看起来与iOS本机相同的自定义推送通知提示。这里是另一个例子:

输入图像描述


2

1

使用我的UIAlertController类别,您只需一行代码即可完成,并替换应用程序中现有的警报,请在这里查看。

enter image description here


那本来是很好的,但不幸的是它在iPad上无法与操作表一起使用。 - Peter Johnson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接