美文网首页iOSiOS开发ios
我把系统UIAlertView的代理写成blocks了(增加ru

我把系统UIAlertView的代理写成blocks了(增加ru

作者: icoder | 来源:发表于2015-07-23 13:55 被阅读2120次

当一个控制器里面有很多UIAlertView 的时候,你要获取当前用户操作的是那个UIAlertView 很是麻烦,先你要设置他的tag 值,然后你在代理里面要判断tag,要是有10个,这时候你就凌乱了,忘了自己设置了那个是哪个。

那我们今天就把UIAlertView改成block回调方式,大家可以参考参考,顺便把UIActionSheet,UIImagepickerViewcontroller 也写成自己的blocks。
大家也跟我一起自定义个UIAlertView吧
还是先看下效果图吧:

alert.gif

一.常规blocks封装

1.新建一个继承自NSObject的ICInfomationView
在ICInfomationView.h 文件中我们加入#import <UIKit/UIKit.h>
写一个blocks 变量类型,我们下面使用
<pre>typedef void (^ClickAtIndexBlock)(NSInteger buttonIndex);</pre>
遵循 <UIAlertViewDelegate> 协议,因为我们还是用系统的

2.定义一个类方法,我们这个方法接受我们在使用的时候传入的参数
// 我们设置的参数名都是模仿系统的名字来的
<pre><code>+(UIAlertView )initWithTitle:(NSString)title message:(NSString *)messge cancleButtonTitle:(NSString )cancleButtonTitle OtherButtonsArray:(NSArray)otherButtons clickAtIndex:(ClickAtIndexBlock) clickAtIndex;
</code></pre>

在ICInfomationView.m文件中
在头部我们定义一个static 的blocks 变量
static ClickAtIndexBlock _ClickAtIndexBlock;
-实现这个类方法
<pre><code>
+(UIAlertView )initWithTitle:(NSString)title message:(NSString *)messge cancleButtonTitle:(NSString )cancleButtonTitle OtherButtonsArray:(NSArray)otherButtons clickAtIndex:(ClickAtIndexBlock) clickAtIndex;

{
_ClickAtIndexBlock = [clickAtIndex copy];
UIAlertView *Al = [[UIAlertView alloc] initWithTitle:title message:messge delegate:self cancelButtonTitle:cancleButtonTitle otherButtonTitles: nil];
for (NSString *otherTitle in otherButtons) {
[Al addButtonWithTitle:otherTitle];
}
[Al show];
return Al;
}
</code></pre>

-实现UIAlertView 的两个代理

<pre><code>

pragma mark UIAlertViewDelegate

+(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
_ClickAtIndexBlock(buttonIndex);
}

+(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
_ClickAtIndexBlock = nil;
}
</code></pre>

到此我们自己封装的UIAlertView结束了, 以后要是用的时候非常简单,就一句代码,再也不用tag值和遵守协议实现代理了
<pre></code>
[ICInfomationView initWithTitle:@"哈哈,我没有使用代理,我是blocks" message:@"呵呵" cancleButtonTitle:@"好吧" OtherButtonsArray:@[@"嗯呢"] clickAtIndex:^(NSInteger buttonAtIndex) {
NSLog(@"click index ====%ld",(long)buttonAtIndex);
}];

</code></pre>

二.增加使用 runtime 封装方法

runtime用的最多的就是关联(Association)
1、建立关联
objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
参数解释
object:关联对象(id 可以为任意对象)
key :常量键
value:值(id 可以是任意值)
objc_AssociationPolicy:对象关联策略

解释:任意对象可以通过一个常量键关联任意值

2、获得关联
objc_getAssociatedObject(id object, const void *key)

object:关联对象(id 可以为任意对象)
key :常量
解释:通过一个键获得一个对象关联值

本程序中用到的两个方法
<pre></code>
-(void)setClickBlock:(ClickAtIndexBlock)block{
objc_setAssociatedObject(self, IC_alertView_Block, block, OBJC_ASSOCIATION_COPY);
}
-(ClickAtIndexBlock)clickBlock{
return objc_getAssociatedObject(self, IC_alertView_Block);
}
</code></pre>

UIAlertView原生代理调用

<pre></code>

pragma mark UIAlertViewDelegate

+(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (alertView.clickBlock) {

    alertView.clickBlock(buttonIndex);
}

}
</code></pre>

猛戳代码github点击代码

相关文章

网友评论

  • HHHHHHHHHHD:你的这个有问题的 :fearful:
    icoder::smiley: 啥子问题?
  • 我不是掌柜:为什么block处理的时候使用的是类方法的delegate method
    icoder:初始UIAlertView传递的self是class self 不是对象self
  • visual_:楼主,测试了demo,点击按钮,回调了2次?
    icoder:@霖溦 恩 注意到了 更新了代码 谢谢
    霖溦:@MacChark
    楼主的这个方法实现出了问题,导致alert弹出和消失时,block被回调了两次
    +(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
    {
    if (alertView.clickBlock) {

    alertView.clickBlock(buttonIndex);
    }
    }
  • 0ae8e443fa6e:请问下楼主,那两个代理方法是怎么打出来的。还是类方法
    icoder:@格式化油条我有空把ActionSheet的也贴出来
  • dbebbc694bfc:用runtime更好一些
    icoder:已经用runtime 欢迎指导哈@我是彩笔
  • 风了个1:看起来好简单。再也不用系统代理了

本文标题:我把系统UIAlertView的代理写成blocks了(增加ru

本文链接:https://www.haomeiwen.com/subject/czapqttx.html