UIAlertController

【iOS】UI——关于UIAlertController类(警告对话框) 在UI学习中,我们发现UIAlertView在iOS 9中已经被废弃,我们找到UIAlertController来代替UIAlertView实现弹出框的功能,从而有了这篇关于UIAlertController的学习笔记。 阅读详情


在iOS 8中,UIAlertController在功能上是和UIAlertView以及UIActionSheet相同的,UIAlertController以一种模块化替换的方式来代替这两货的功能和作用。是使用对话框(alert)还是使用上拉菜单(action sheet),就取决于在创建控制器时,您是如何设置首选样式的。

一个简单的对话框例子

您可以比较一下两种不同的创建对话框的代码,创建基础UIAlertController的代码和创建UIAlertView的代码非常相似:

Objective-C版本:

1
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"标题" message:@"这个是UIAlertController的默认样式" preferredStyle:UIAlertControllerStyleAlert];

swift版本:

1
var alertController = UIAlertController(title: "标题", message: "这个是UIAlertController的默认样式", preferredStyle: UIAlertControllerStyle.Alert)

同创建UIAlertView相比,我们无需指定代理,也无需在初始化过程中指定按钮。不过要特别注意第三个参数,要确定您选择的是对话框样式还是上拉菜单样式。

通过创建UIAlertAction的实例,您可以将动作按钮添加到控制器上。UIAlertAction由标题字符串、样式以及当用户选中该动作时运行的代码块组成。通过UIAlertActionStyle,您可以选择如下三种动作样式:常规(default)、取消(cancel)以及警示(destruective)。为了实现原来我们在创建UIAlertView时创建的按钮效果,我们只需创建这两个动作按钮并将它们添加到控制器上即可。

Objective-C版本:

1
2
3
4
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:cancelAction];
[alertController addAction:okAction];

swift版本:

1
2
3
4
var cancelAction = UIAlertAction(title: "取消", style: UIAlertActionStyle.Cancel, handler: nil)
var okAction = UIAlertAction(title: "好的", style: UIAlertActionStyle.Default, handler: nil)
alertController.addAction(cancelAction)
alertController.addAction(okAction)

最后,我们只需显示这个对话框视图控制器即可:

Objective-C版本:

1
[self presentViewController:alertController animated:YES completion:nil];

swift版本:

1
self.presentViewController(alertController, animated: true, completion: nil)

06.png

UIAlertController默认样式

按钮显示的次序取决于它们添加到对话框控制器上的次序。一般来说,根据苹果官方制定的《iOS 用户界面指南》,在拥有两个按钮的对话框中,您应当将取消按钮放在左边。要注意,取消按钮是唯一的,如果您添加了第二个取消按钮,那么你就会得到如下的一个运行时异常:

* Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘UIAlertController can only have one action with a style of UIAlertActionStyleCancel’

异常信息简洁明了,我们在此就不赘述了。

“警示”样式

什么是“警示”样式呢?我们先不着急回答这个问题,先来看一下下面关于“警示”样式的简单示例。在这个示例中,我们将前面的示例中的“好的”按钮替换为了“重置”按钮。

Objective-C版本:

1
2
UIAlertAction *resetAction = [UIAlertAction actionWithTitle:@"重置" style:UIAlertActionStyleDestructive handler:nil];
[alertController addAction:resetAction];

swift版本:

1
2
var resetAction = UIAlertAction(title: "重置", style: UIAlertActionStyle.Destructive, handler: nil)
alertController.addAction(resetAction)

07.png

“警示”样式

可以看出,我们新增的那个“重置”按钮变成了红色。根据苹果官方的定义,“警示”样式的按钮是用在可能会改变或删除数据的操作上。因此用了红色的醒目标识来警示用户。

文本对话框

UIAlertController极大的灵活性意味着您不必拘泥于内置样式。以前我们只能在默认视图、文本框视图、密码框视图、登录和密码输入框视图中选择,现在我们可以向对话框中添加任意数目的UITextField对象,并且可以使用所有的UITextField特性。当您向对话框控制器中添加文本框时,您需要指定一个用来配置文本框的代码块。

举个栗子吧,要重新建立原来的登录和密码样式对话框,我们可以向其中添加两个文本框,然后用合适的占位符来配置它们,最后将密码输入框设置使用安全文本输入。

Objective-C版本:

1
2
3
4
5
6
7
8
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"文本对话框" message:@"登录和密码对话框示例" preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField){
    textField.placeholder = @"登录";
}];
[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
    textField.placeholder = @"密码";
    textField.secureTextEntry = YES;
}];

swift版本:

1
2
3
4
5
6
7
8
9
alertController.addTextFieldWithConfigurationHandler { 
(textField: UITextField!) -> Void in
    textField.placeholder = "登录"
}
alertController.addTextFieldWithConfigurationHandler { 
(textField: UITextField!) -> Void in
    textField.placeholder = "密码"
    textField.secureTextEntry = true
}

在“好的”按钮按下时,我们让程序读取文本框中的值。

Objective-C版本:

1
2
3
4
5
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
    UITextField *login = alertController.textFields.firstObject;
    UITextField *password = alertController.textFields.lastObject;
    ...
}];

swift版本:

1
2
3
4
5
var okAction = UIAlertAction(title: "好的", style: UIAlertActionStyle.Default) {
(action: UIAlertAction!) -> Void in
    var login = alertController.textFields?.first as UITextField
    var password = alertController.textFields?.last as UITextField
}

如果我们想要实现UIAlertView中的委托方法alertViewShouldEnableOtherButton:方法的话可能会有一些复杂。假定我们要让“登录”文本框中至少有3个字符才能激活“好的”按钮。很遗憾的是,在UIAlertController中并没有相应的委托方法,因此我们需要向“登录”文本框中添加一个Observer。Observer模式定义对象间的一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。我们可以在构造代码块中添加如下的代码片段来实现。

Objective-C版本:

1
2
3
4
[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField){
    ...
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(alertTextFieldDidChange:) name:UITextFieldTextDidChangeNotification object:textField];
}];

swift版本:

1
2
3
4
5
alertController.addTextFieldWithConfigurationHandler {
(textField: UITextField!) -> Void in
    ...
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("alertTextFieldDidChange:"), name: UITextFieldTextDidChangeNotification, object: textField)
}

当视图控制器释放的时候我们需要移除这个Observer,我们通过在每个按钮动作的handler代码块(还有其他任何可能释放视图控制器的地方)中添加合适的代码来实现它。比如说在okAction这个按钮动作中:

Objective-C版本:

1
2
3
4
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
    ...
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];
}];

swift版本:

1
2
3
4
5
var okAction = UIAlertAction(title: "好的", style: UIAlertActionStyle.Default) {
(action: UIAlertAction!) -> Void in
    ...
    NSNotificationCenter.defaultCenter().removeObserver(self, name: UITextFieldTextDidChangeNotification, object: nil)
}

在显示对话框之前,我们要冻结“好的”按钮

Objective-C版本:

1
okAction.enabled = NO;

swift版本:

1
okAction.enabled = false

接下来,在通知观察者(notification observer)中,我们需要在激活按钮状态前检查“登录”文本框的内容。

Objective-C版本:

1
2
3
4
5
6
7
8
- (void)alertTextFieldDidChange:(NSNotification *)notification{
    UIAlertController *alertController = (UIAlertController *)self.presentedViewController;
    if (alertController) {
        UITextField *login = alertController.textFields.firstObject;
        UIAlertAction *okAction = alertController.actions.lastObject;
        okAction.enabled = login.text.length > 2;
    }
}

swift版本:

1
2
3
4
5
6
7
8
func alertTextFieldDidChange(notification: NSNotification){
    var alertController = self.presentedViewController as UIAlertController?
    if (alertController != nil) {
        var login = alertController!.textFields?.first as UITextField
        var okAction = alertController!.actions.last as UIAlertAction
        okAction.enabled = countElements(login.text) > 2
    }
}

08.png

UIAlertController的登录和密码对话框示例

好了,现在对话框的“好的”按钮被冻结了,除非在“登录”文本框中输入3个以上的字符:

上拉菜单

当需要给用户展示一系列选择的时候(选择恐惧症患者杀手),上拉菜单就能够派上大用场了。和对话框不同,上拉菜单的展示形式和设备大小有关。在iPhone上(紧缩宽度),上拉菜单从屏幕底部升起。在iPad上(常规宽度),上拉菜单以弹出框的形式展现。

创建上拉菜单的方式和创建对话框的方式非常类似,唯一的区别是它们的形式。

Objective-C版本:

1
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"保存或删除数据" message:@"删除数据将不可恢复" preferredStyle: UIAlertControllerStyleActionSheet];

swift版本:

1
var alertController = UIAlertController(title: "保存或删除数据", message: "删除数据将不可恢复", preferredStyle: UIAlertControllerStyle.ActionSheet)

添加按钮动作的方式和对话框相同。

Objective-C版本:

1
2
3
4
5
6
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
UIAlertAction *deleteAction = [UIAlertAction actionWithTitle:@"删除" style:UIAlertActionStyleDestructive handler:nil];
UIAlertAction *archiveAction = [UIAlertAction actionWithTitle:@"保存" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:cancelAction];
[alertController addAction:deleteAction];
[alertController addAction:archiveAction];

swift版本:

1
2
3
4
5
6
var cancelAction = UIAlertAction(title: "取消", style: UIAlertActionStyle.Cancel, handler: nil)
var deleteAction = UIAlertAction(title: "删除", style: UIAlertActionStyle.Destructive, handler: nil)
var archiveAction = UIAlertAction(title: "保存", style: UIAlertActionStyle.Default, handler: nil)
alertController.addAction(cancelAction)
alertController.addAction(deleteAction)
alertController.addAction(archiveAction)

您不能在上拉菜单中添加文本框,如果您强行作死添加了文本框,那么就会荣幸地得到一个运行时异常:

* Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘Text fields can only be added to an alert controller of style UIAlertControllerStyleAlert’

同样,简单的异常说明,我们也不多说了。

接下来我们就可以在iPhone或者其他紧缩宽度的设备上展示了,不出我们所料,运行得很成功。

Objective-C版本:

1
[self presentViewController:alertController animated:YES completion:nil];

swift版本:

1
self.presentViewController(alertController, animated: true, completion: nil)

09.png

iPhone上的上拉菜单效果

如果上拉菜单中有“取消”按钮的话,那么它永远都会出现在菜单的底部,不管添加的次序是如何(就是这么任性)。其他的按钮将会按照添加的次序从上往下依次显示。《iOS 用户界面指南》要求所有的“毁坏”样式按钮都必须排名第一(红榜嘛,很好理解的,对不对?)。

别激动得太早,我们现在还有一个很严重的问题,这个问题隐藏得比较深。当我们使用iPad或其他常规宽度的设备时,就会得到一个运行时异常:

Terminating app due to uncaught exception ‘NSGenericException’, reason: ‘UIPopoverPresentationController (<_uialertcontrolleractionsheetregularpresentationcontroller: 0x7fc619588110="">) should have a non-nil sourceView or barButtonItem set before the presentation occurs.’

就如我们之前所说,在常规宽度的设备上,上拉菜单是以弹出框的形式展现。弹出框必须要有一个能够作为源视图或者栏按钮项目的描点(anchor point)。由于在本例中我们是使用了常规的UIButton来触发上拉菜单的,因此我们就将其作为描点。

在iOS 8中我们不再需要小心翼翼地计算出弹出框的大小,UIAlertController将会根据设备大小自适应弹出框的大小。并且在iPhone或者紧缩宽度的设备中它将会返回nil值。配置该弹出框的代码如下:

Objective-C版本:

1
2
3
4
5
6
UIPopoverPresentationController *popover = alertController.popoverPresentationController;
if (popover){
    popover.sourceView = sender;
    popover.sourceRect = sender.bounds;
    popover.permittedArrowDirections = UIPopoverArrowDirectionAny;
}

swift版本:

1
2
3
4
5
6
var popover = alertController.popoverPresentationController
if (popover != nil){
    popover?.sourceView = sender
    popover?.sourceRect = sender.bounds
    popover?.permittedArrowDirections = UIPopoverArrowDirection.Any
}

10.png

iPad上的上拉菜单效果

UIPopoverPresentationController类同样也是在iOS 8中新出现的类,用来替换UIPopoverController的。这个时候上拉菜单是以一个固定在源按钮上的弹出框的形式显示的。

要注意UIAlertController在使用弹出框的时候自动移除了取消按钮。用户通过点击弹出框的外围部分来实现取消操作,因此取消按钮便不再必需。

释放对话框控制器

通常情况下,当用户选中一个动作后对话框控制器将会自行释放。不过您仍然可以在需要的时候以编程方式释放它,就像释放其他视图控制器一样。您应当在应用程序转至后台运行时移除对话框或者上拉菜单。假定我们正在监听UIApplicationDidEnterBackgroundNotification通知消息,我们可以在observer中释放任何显示出来的视图控制器。(参考在viewDidLoad方法中设立observer的示例代码)。

Objective-C版本:

1
2
3
4
5
- (void)didEnterBackground:(NSNotification *)notification
{
  [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];
  [self.presentedViewController dismissViewControllerAnimated:NO completion:nil];
}

swift版本:

1
2
3
4
func didEnterackground(notification: NSNotification){
    NSNotificationCenter.defaultCenter().removeObserver(self, name: UITextFieldTextDidChangeNotification, object: nil)
    self.presentedViewController?.dismissViewControllerAnimated(false, completion: nil)
}

注意,要保证运行安全我们同样要确保移除所有的文本框observer。

我们来总结一下

这篇文章比较长,但是希望能够对您有所帮助。原先的UIAlertView和UIActionSheet类仍然可以在iOS 8中工作得很好,所以没有必要急于更换代码(要知道本文用到的许多函数尽在iOS 8中支持)。本文的代码可以在我的Github主页上找到,包括了AlertController - ObjC以及AlertController - swift

iOS UIAlertController嵌入UITextView 1.Controller继承UITextViewDelegate 2.先创建一个UITextView UITextView *textView = [[UITextView alloc] init]; textView.layer.borderColor = [[UIColor lightGrayColor] CGColor]; textView.layer.borderWidth = 1.0f;... 阅读详情

相关推荐

IOS开发指南之使用UIAlertController与UIAlertView显示提示框

1.UIAlertController支持IOS9或者更高版本。2. UIAlertView支持IOS9之前版本。

1133

【弹出对话框以及提示UIAlertView不可用的解决办法 Objective-C语言】

【弹出对话框 Objective-C语言】

madoca的博客 1387

iOS UIAlertViewController的事件处理

然后,我们添加了两个UIAlertAction按钮,一个是"确定"按钮,另一个是"取消"按钮。通过使用UIAlertViewController,我们可以在iOS应用程序中创建弹窗,并处理按钮的点击事件。您可以根据需要自定义弹窗的标题、消息和按钮,并在按钮的处理程序闭包中编写相应的逻辑代码。在上面的示例代码中,我们已经为"确定"按钮和"取消"按钮添加了处理程序闭包。当用户点击按钮时,这些闭包中的代码会被执行。例如,当用户点击"确定"按钮时,我们可以执行一些操作,比如显示一个提示信息或者执行一些其他任务。

ByteGlide的博客 304

UIAlertViewController详解

Xcode7更新后,苹果不建议使用以前的AlertView和ActionSheet了,而是将二者合一,创建了一个新的视图控制器UIAlertViewController,UIAlertViewController继承自UIViewController,通过改变设置不同的UIAlertControllerStyle来确定显示的是AlertView或者是ActionSheet.通过添加AlertAction来增加按钮,话不多说,贴上自己写的一个小Demo.

Le_Wrynn的博客 1411

奥比中光Gemini335L SDK实战:从标定参数到3D点云转换

本文详细介绍了奥比中光Gemini 335L深度相机的SDK实战应用,重点讲解如何跳过繁琐的棋盘格标定,直接调用出厂预标定参数实现高效的3D点云转换。通过解析内参、外参获取及四种核心坐标转换模式,并结合OpenCV等工具,指导开发者快速将相机集成到机器人抓取、三维测量等项目中,实现开箱即用的3D视觉解决方案。

raspberrypi5的博客 639

本地大模型5:在pycharm用python调用ollama本地大模型

python调用ollama本地大模型

weixin_74825941的博客 8377

UIAlertController使用

UIAlertController基本可以简单的理解为UIAlertController == UIAlertView + UIActionSheet,相比后面两个100%的开发朋友使用过.先简单看下UIAlertView和UIActionSheet的使用和效果 1.UIAlertView使用: UIAlertView*alert = [[UIAlertView alloc]initW

Leemin_ios的博客 1102

电赛MSP430F5529之超声波测距+OLED 显示(含主要代码)

目录 前言 一、超声波介绍 二、部分代码 三、总结 题外话: 前言 哎,又双叒叕,电赛延期了,看起来像是遥遥无期,但是肯定要考虑大局,大家就继续抓紧时间学习知识,巩固自己的知识,更进一步。好了,今天主要是继承上一篇博文(OLED显示)写的,主要是写超声波测距的(US-015) 一、超声波介绍 利用TI公司的MSP430F5529单片机+超声波模块+OLED 实现 这里主要是利用单片机定时器的捕获功能来捕获超声波高电平持续时间,再计算得到距离,最后再在OLED 屏幕上显示出来,上图

不说二话的自家人的博客 1万+

iOS UIAlertController

运行环境: Xcode7.2.1,iOS Simulator9.2 语言: Objective-C、Swift 关于UIAlertController的使用,主要有三种不同的方式: 1.简单的UIAlertController形式; 2.带有输入框的UIAlert...

chongcuan4403的博客 239

爬取国家统计局最近10年年度数据

一、编码流程 1.目标网址:https://data.stats.gov.cn/easyquery.htm?cn=C01 2.编码思路: (1) 解析左侧指标树,实现4级标签定位 (难点:层层嵌套,下一级指标的xpath路径以上一级指标为基础;不是所有二级指标都含有三和四级指标,需要进行判断) (2) 使用selenium webdriver 点选指标,加载出右侧表格数据 (难点:当指标无法在全局页面显示时,需向下拖动滚动条) (3) 解析右侧数据,实现数据存储 3.使用模块: (1) selenium:解

weixin_39645690的博客 4560

电机控制必看!SVPWM谐波优化:5段式与7段式全参数对比测试

本文通过实测数据,对比分析了电机控制中5段式与7段式SVPWM控制算法的谐波性能。实验表明,7段式SVPWM在电流波形质量(THD)和低速性能上更优,而5段式SVPWM则在开关损耗和效率方面表现突出。文章为工程师在不同应用场景(如对噪音、效率或动态响应的侧重)下的算法选型提供了清晰的依据和实用的工程指南。

weixin_28331555的博客 178

Swift - UIAlertController

添加AlertController import UIKit var imageView:UIImageView! class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let button = UIButton(frame: CG...

iOS - Swift 1228

SAP特殊采购类80实战:跨工厂生产配置避坑指南(附完整测试流程)

本文深入解析SAP特殊采购类80在跨工厂生产场景下的实战应用与配置要点。文章从核心业务逻辑出发,详细拆解了后台配置、主数据与BOM的“双工厂”思维模式,并提供了从创建需求到成品收货的完整测试流程。重点揭示了多层BOM下的需求传递陷阱及常见报错解决方案,旨在帮助SAP顾问及用户规避实施风险,实现资源的灵活调度与流程自动化。

wind6的博客 1139

ios UIAlertController弹出框的使用

运行效果 示例demo // // ViewController.m // alertViewAndSheet // // Created by 黄海农业 on 2019/6/17. // Copyright © 2019 黄海农业. All rights reserved. // #import "ViewController.h" @interface ViewControlle...

ITzhongzi的博客 1890

FLAC3D数值三轴测试

本文介绍了使用FLAC3D进行数值三轴测试的命令流程。通过建立圆柱体模型,设置Mohr-Coulomb本构模型及材料参数,施加边界条件和荷载,并定义Fish函数监测应变和应力。命令包括模型创建、网格划分、材料属性定义、边界约束、荷载施加以及结果监测等步骤。该流程可用于模拟岩土材料在三轴条件下的力学响应,为数值分析提供参考。完整代码可从指定链接下载获取。

qq_36980284的博客 99

【温室气体数据集】全球总碳柱观测网络 TCCON

【温室气体数据集】全球总碳柱观测网络 TCCON

WW、forever的博客 437

UIalertController

// //  ViewController.m //  alert // //  Created by 朱敏 on 15/7/13. //  Copyright © 2015年 helinyu. All rights reserved. // #import "ViewController.h" @interface ViewController () @

bruscar的专栏 718

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

IOS8 UIAlertController 弹框

IOS8中,Apple将UIActionSheet和UIAlertView整合成一个接口UIAlertController。 原来的是一个view,展示在window视图之上。现在改成了controller,展示方式变成由当前的controller直接present出来。 下面看看具体的接口: [html] view plaincopy

Ray_win的专栏 1178

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

UIAlertController的使用

一、UIAlertController的使用 从这个类的名字我们就可以看出,对于警示控件,设计的思路不再是View而是Controller。通过present和push进行呼出,而不是以前的show方法。另一个机制改变的地方是,其中按钮的触发方法不再通过代理处理,而是将按钮封装成了类:...

chengpoujue4939的博客 278

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

UIAlertController 添加 UITextField

UIAlertController的使用。

心虽远,情未变,乐依然。 2208
上一篇: IOS中常用的定时器有三种
下一篇: Cocoapods安装步骤
SpringJustin
博客等级 码龄11年 2粉丝 44原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值