Objective-C Runtime之着魔的UIAlertView

   2023-02-09 学习力0
核心提示:上篇文章写的是Runtime的一个入门教程,刚哥问我那个Associated Objects加回调是啥时候用,那我就来告诉你啦!我们在使用UIAlertView的时候用的多。传统的UIAlertView:在一个类中有多个UIAlertView,不同的UIAlertView对应不同的事件,我们使用的传统方法如

上篇文章写的是Runtime的一个入门教程,刚哥问我那个Associated Objects加回调是啥时候用,那我就来告诉你啦!我们在使用UIAlertView的时候用的多。

传统的UIAlertView:

在一个类中有多个UIAlertView,不同的UIAlertView对应不同的事件,我们使用的传统方法如下:

 1 #pragma mark - action method
 2 
 3 - (IBAction)firstButtonClick:(id)sender {
 4     UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"title" message:@"message" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"ok", nil];
 5     alertView.tag = 1001;
 6     [alertView show];
 7 }
 8 
 9 - (IBAction)secondButtonClick:(id)sender {
10     UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"title" message:@"message" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"ok", nil];
11     alertView.tag = 1002;
12     [alertView show];
13 }
14 
15 - (IBAction)ThirdButtonClick:(id)sender {
16     UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"title" message:@"message" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"ok", nil];
17     alertView.tag = 1003;
18     [alertView show];
19 }
20 
21 #pragma mark - delegate method
22 
23 - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
24 {
25     if (alertView.tag == 1001) {
26         if (buttonIndex == 1) {
27             NSLog(@"普通alertView1001执行ok");
28         }
29     } else if (alertView.tag == 1002) {
30         if (buttonIndex == 1) {
31             NSLog(@"普通alertView1002执行ok");
32         }
33     } else if (alertView.tag == 1003) {
34         if (buttonIndex == 1) {
35             NSLog(@"普通alertView1003执行ok");
36         }
37     }
38 }

 

我们要给每个UIAlertView赋值一个tag值,在delegate方法中还要进行tag的判断以及buttonIndex的判断,太繁琐了。

着魔的UIAlertView:

下面我们使用Category和Associated Objects进行魔法修改

创建一个UIAlertView的Category

UIAlertView+ActionBlock.h

1 #import <UIKit/UIKit.h>
2 
3 typedef void (^AlertCallBack)(UIAlertView *, NSUInteger);
4 
5 @interface UIAlertView (ActionBlock)<UIAlertViewDelegate>
6 
7 @property (nonatomic, copy) AlertCallBack callBack;
8 
9 @end

 

UIAlertView+ActionBlock.m

 1 #if TARGET_IPHONE_SIMULATOR
 2 #import <objc/objc-runtime.h>
 3 #else
 4 #import <objc/runtime.h>
 5 #import <objc/message.h>
 6 #endif
 7 
 8 @implementation UIAlertView (ActionBlock)
 9 
10 - (void)setCallBack:(AlertCallBack)callBack
11 {
12     objc_setAssociatedObject(self, @selector(callBack), callBack, OBJC_ASSOCIATION_COPY_NONATOMIC);
13     self.delegate = self;
14 }
15 
16 - (AlertCallBack)callBack
17 {
18     return objc_getAssociatedObject(self, @selector(callBack));
19 }
20 
21 #pragma mark - delegate method
22 
23 - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
24 {
25     if (self.callBack) {
26         self.callBack(alertView, buttonIndex);
27     }
28 }

 

在主类中取消delegate,使用block属性

 1 #pragma mark - action method
 2 
 3 - (IBAction)firstButtonClick:(id)sender {
 4     UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"title" message:@"message" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"ok", nil];
 5     alertView.callBack = ^(UIAlertView *alertView, NSUInteger buttonIndex){
 6         if (buttonIndex == 1) {
 7             NSLog(@"魔法alertView1001执行ok");
 8         }
 9     };
10     [alertView show];
11 }
12 
13 - (IBAction)secondButtonClick:(id)sender {
14     UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"title" message:@"message" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"ok", nil];
15     alertView.callBack = ^(UIAlertView *alertView, NSUInteger buttonIndex){
16         if (buttonIndex == 1) {
17             NSLog(@"魔法alertView1002执行ok");
18         }
19     };
20     [alertView show];
21 }
22 
23 - (IBAction)ThirdButtonClick:(id)sender {
24     UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"title" message:@"message" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"ok", nil];
25     alertView.callBack = ^(UIAlertView *alertView, NSUInteger buttonIndex){
26         if (buttonIndex == 1) {
27             NSLog(@"魔法alertView1003执行ok");
28         }
29     };
30     [alertView show];
31 }

 

我们通过使用Category给UIAlertView扩展了一个block属性,当block被设置后就会调用setCallBack方法,触发self.delegate = self,即主类中的UIAlertView的delegate方法被Category中的方法覆盖。这样不仅有效解决问题,还解决了其他人修改该类的安全性(block被去掉后,原delegate恢复)

如下不给tag值为1003的UIAlertView设置block,即调用原delegate方法。

 1 - (IBAction)firstButtonClick:(id)sender {
 2     UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"title" message:@"message" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"ok", nil];
 3     alertView.callBack = ^(UIAlertView *alertView, NSUInteger buttonIndex){
 4         if (buttonIndex == 1) {
 5             NSLog(@"魔法alertView1001执行ok");
 6         }
 7     };
 8     alertView.tag = 1001;
 9     [alertView show];
10 }
11 
12 - (IBAction)secondButtonClick:(id)sender {
13     UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"title" message:@"message" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"ok", nil];
14     alertView.callBack = ^(UIAlertView *alertView, NSUInteger buttonIndex){
15         if (buttonIndex == 1) {
16             NSLog(@"魔法alertView1002执行ok");
17         }
18     };
19     alertView.tag = 1002;
20     [alertView show];
21 }
22 
23 - (IBAction)ThirdButtonClick:(id)sender {
24     UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"title" message:@"message" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"ok", nil];
25     alertView.tag = 1003;
26     [alertView show];
27 }
28 
29 - (IBAction)fourthButtonClick:(id)sender {
30     UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"title" message:@"message" preferredStyle:UIAlertControllerStyleAlert];
31     UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"cancel" style:UIAlertActionStyleCancel handler:nil];
32     UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction *alertAction){
33         NSLog(@"如果你是iOS8以上的应用,这个适合你,简单明了");
34     }];
35     [alertController addAction:cancelAction];
36     [alertController addAction:okAction];
37     [self presentViewController:alertController animated:YES completion:nil];
38 }
39 
40 #pragma mark - delegate method
41 
42 - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
43 {
44     if (alertView.tag == 1001) {
45         if (buttonIndex == 1) {
46             NSLog(@"普通alertView1001执行ok");
47         }
48     } else if (alertView.tag == 1002) {
49         if (buttonIndex == 1) {
50             NSLog(@"普通alertView1002执行ok");
51         }
52     } else if (alertView.tag == 1003) {
53         if (buttonIndex == 1) {
54             NSLog(@"普通alertView1003执行ok");
55         }
56     } else if (alertView.tag == 1004) {
57         if (buttonIndex == 1) {
58             NSLog(@"普通alertView1004执行ok");
59         }
60     }
61 }

 

Objective-C Runtime之着魔的UIAlertView

相关Demo下载:

https://github.com/ianisme/UIAlertViewBYRuntime_Demo

总结:

通过Associated Objects我们有效的解决了UIAlertView的繁琐问题,如果您是开发iOS8以上的应用,建议您弃用UIAlertView,苹果的UIAlertController已经有了更好的解决方案。

 
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • 《黑马程序员》 category分类的使用(Objective
    分类的作用:在不改变原来类的基础上,可以给类增加一些方法。使用注意 : ①  分类只能增加方法,不可以增加成员变量                ②  分类的方法在实现中可以访问成员变量,不过成员变量必须手动实现。               
    03-16
  • Objective-C学习—UIScrollView控件使用
    Objective-C学习—UIScrollView控件使用
    一、知识点简单介绍1.UIScrollView控件是什么?(1)移动设备的屏幕⼤大⼩小是极其有限的,因此直接展⽰示在⽤用户眼前的内容也相当有限(2)当展⽰示的内容较多,超出⼀一个屏幕时,⽤用户可通过滚动⼿手势来查看屏幕以外的内容(3)普通的UIView不具备滚动功能
    03-16
  • Objective-C Runtime(转)
    博主地址: http://yulingtianxia.com/blog/2014/11/05/objective-c-runtime/曾经觉得Objc特别方便上手,面对着 Cocoa 中大量 API,只知道简单的查文档和调用。还记得初学 Objective-C 时把[receiver message]当成简单的方法调用,而无视了“发送消息”这句话
    03-08
  • iOS扩展——Objective-C开发编程规范 简单io扩展实验代码
    iOS扩展——Objective-C开发编程规范 简单io扩
      最近准备开始系统学习一个完整项目的开发流程和思路,在此之前,我们需要对iOS的开发变成规范进行更系统和详尽的学习,随意对编程规范进行了整理和学习。本文内容主要转载自:Objective-C-Coding-Guidelines-In-Chinese  此外,这篇文章所说的一些常见
    03-08
  • Objective-C利用协议实现回调函数
    实现一个显示文字为测试的视图,然后经过3秒钟测试文字变为回调函数文字。相应的截图如下:  实现的代码如下:定义协议:#import UIKit/UIKit.h @protocol NoteDelegate //回调函数 -(void)messageCallBack:(NSString *)string; @end 调用协议:#impor
    02-10
  • 刨根问底Objective-C Runtime(1)- Self & S
      刨根问底Objective-C Runtime(1)- SelfSuper - Chun Tips专注iOS开发 刨根问底Objective-C Runtime(1)- SelfSuper前言关于Objective-C Runtime一篇好的文档 : Understanding the Objective-C Runtime译文地址为: http://blog.cocoabit.com/blog/2
    02-10
  • Objective-C利用协议实现回调函数
    实现一个显示文字为测试的视图,然后经过3秒钟测试文字变为回调函数文字。相应的截图如下: 实现的代码如下:定义协议:#import UIKit/UIKit.h @protocol NoteDelegate//回调函数-(void)messageCallBack:(NSString *)string;@end  调用协议:#import Founda
    02-10
  • Objective-c开发中混合使用ARC
    首选“Compile Sources”的位置:选中工程-TARGETS-相应的target然后选中右侧的“Build Phases”,向下就找到“Compile Sources”了。如何在未使用arc的工程中引入一个使用了arc特性的文件:对相应的文件添加:-fobjc-arc参数如何在arc工程中引用未使用arc的文件
    02-10
  • Objective C运行时(runtime)技术总结,好强大
    前言:         Objective C的runtime技术功能非常强大,能够在运行时获取并修改类的各种信息,包括获取方法列表、属性列表、变量列表,修改方法、属性,增加方法,属性等等,本文对相关的几个要点做了一个小结。目录:(1)使用class_replaceMethod/cla
    02-09
  • Programming With Objective-C---- Introductio
    a:link { color: rgba(88, 114, 210, 1); text-decoration: none }a:visited { color: rgba(88, 114, 210, 1); text-decoration: none }a:hover { color: rgba(173, 189, 248, 1); text-decoration: none }a:active { color: rgba(0, 0, 255, 1); text-decora
    02-09
点击排行