zoukankan      html  css  js  c++  java
  • UIAlertController基本使用和循环引用问题

    UIAlertController是苹果在iOS8里新推出的一个玩意。它把之前我们用来现实提示框的UIAlertView和UIAlertAction集成在一起了,而且不论在iPhone还是iPad上都能统一使用啦。

    从UIAlertController的定义可以发现

    NS_CLASS_AVAILABLE_IOS(8_0) @interface UIAlertController : UIViewController

    它是一个UIViewControll,就是说你面前的这个在屏幕中间或是屏幕下方显示的小窗口是一个控制器了,不在是一个UIView。一段简洁的代码来说明它的基本使用

     1 UIAlertController *alert=[UIAlertController alertControllerWithTitle:@"new alert" message:@"this is a alert viewController" preferredStyle:UIAlertControllerStyleAlert];
     2     
     3     
     4     [alert addAction:[UIAlertAction actionWithTitle:@"submit" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
     5         NSLog(@"click submit button");
     6         
     7         NSLog(@"first textField's text is %@,the second textField's text is %@",[alert.textFields.firstObject text],[alert.textFields.lastObject text]);
     8     }]];
     9     [alert addAction:[UIAlertAction actionWithTitle:@"cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
    10         NSLog(@"click cancel button");
    11     }]];
    12     [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
    13         
    14         textField.textColor=[UIColor orangeColor];
    15     }];
    16     [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
    17         textField.secureTextEntry=YES;
    18     }];
    19     
    20     //现实控制器  首先想到的是modal  presentViewController方法
    21     [self presentViewController:alert animated:YES completion:nil];
    View Code

    使用特点:

    1、通过preferredStyle来确定显示风格,它有两个选择

      UIAlertControllerStyleActionSheet = 0,

          UIAlertControllerStyleAlert

    2、通过addAction来添加按钮,这个方法提供block来实现按钮点击的具体行为,各个按钮的处理分开,互补干扰

    3、通过addTextFieldWithConfigurationHandler来添加文本框,在这个方法的block里可以自由设置文本框的一些样式,更加方便

    4、因为UIAlertController是控制器,控制器的显示首先想到的是用presentViewController方法

    打印内容如下

    2015-03-16 17:31:30.479 iOS8NewFeature[4247:152311] click submit button

    2015-03-16 17:31:30.480 iOS8NewFeature[4247:152311] first textField's text is luseike,the second textField's text is 123

    ————————————————————————————————————————————————————————————————————————

    在打印出文本框内容的block内,看上去貌似有些循环引用的感觉,alert身上有个action的block,block内部又引用着alert,为了弄清楚是UIAlertController没有释放还是我们的代码有问题,可以自定义一个继承于UIAlertController的类,实现其dealloc方法来看一下

    #import "MyViewController.h"
    
    @interface MyViewController ()
    
    @end
    
    @implementation MyViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    }
    
    -(void)dealloc{
        NSLog(@"MyViewController--dealloc");
    }
    View Code

    当不访问文本框的时候,自定义的UIAlertController是能够成功释放的

    2015-03-16 17:36:33.798 iOS8NewFeature[4270:154130] click submit button

    2015-03-16 17:36:33.799 iOS8NewFeature[4270:154130] MyViewController--dealloc

     为了能够访问alert身上的文本框的同时正常释放,这里我用一个若引用来解决,加一句代码

    1 __weak typeof (alert) weekAlert=alert;
    2     [alert addAction:[UIAlertAction actionWithTitle:@"submit" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
    3         NSLog(@"click submit button");
    4         
    5         NSLog(@"first textField's text is %@,the second textField's text is %@",[weekAlert.textFields.firstObject text],[weekAlert.textFields.lastObject text]);
    6     }]];
    View Code

    第一行代码来声明一个指向alert变量的若饮用,block内部使用这个若引用来访问textFeild对象,打印结果如下

    2015-03-16 17:39:57.327 iOS8NewFeature[4288:155347] click submit button

    2015-03-16 17:39:57.328 iOS8NewFeature[4288:155347] first textField's text is luseike,the second textField's text is 123456

    2015-03-16 17:39:57.328 iOS8NewFeature[4288:155347] MyViewController--dealloc

    这样既能成功访问又不造成循环引用的问题了

    ——————————————————————————————————————————————————————————————————————

    解决了循环引用的问题,还有个常用的功能就是如何获取添加到UIAlertController里面文本框值的改变呢?

    当然会比较容易想到用通知的方式

    [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
            textField.textColor=[UIColor orangeColor];
            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(userFieldDidChange:) name:UITextFieldTextDidChangeNotification object:textField];
        }];
    
    
    //通知的监听
    -(void)userFieldDidChange:(NSNotification *)notification{
        
    }
    View Code

    这个方案有两个需要注意的地方

    1、不能直接拿到textField对象

    2、需要主要在UIAlertController消失的时候去释放通知,比较麻烦

    其实UITextField直接继承至UIControl,我比较倾向于通过addTarget的方式监听,而且直接把UITextField作为参数传到监听方法中

    [textField addTarget:self action:@selector(userFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
    
    -(void)userFieldDidChange:(UITextField *)userField{
        NSLog(@"%@",userField.text);
    }
    View Code

    打印结果如下:

    2015-03-16 17:57:54.074 iOS8NewFeature[4314:160573] l

    2015-03-16 17:57:55.291 iOS8NewFeature[4314:160573] lu

    2015-03-16 17:57:56.003 iOS8NewFeature[4314:160573] lus

    2015-03-16 17:57:56.649 iOS8NewFeature[4314:160573] luse

    2015-03-16 17:57:57.026 iOS8NewFeature[4314:160573] lusei

    2015-03-16 17:57:57.582 iOS8NewFeature[4314:160573] luseik

    2015-03-16 17:57:57.874 iOS8NewFeature[4314:160573] luseike

    我们的生活是如此的美好,哈哈!!!!!!!!!

  • 相关阅读:
    Entity Framework Core 2.0 新特性
    asp.net core部署时自定义监听端口,提高部署的灵活性
    asp.net core使用jexus部署在linux无法正确 获取远程ip的解决办法
    使用xshell连接服务器,数字键盘无法使用解决办法
    使用Jexus 5.8.2在Centos下部署运行Asp.net core
    【DevOps】DevOps成功的八大炫酷工具
    【Network】Calico, Flannel, Weave and Docker Overlay Network 各种网络模型之间的区别
    【Network】UDP 大包怎么发? MTU怎么设置?
    【Network】高性能 UDP 应该怎么做?
    【Network】golang 容器项目 flannel/UDP相关资料
  • 原文地址:https://www.cnblogs.com/luseike/p/4342397.html
Copyright © 2011-2022 走看看