IOS开发之自定义Button(集成三种回调模式)

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

前面在做东西的时候都用到了storyboard,在今天的代码中就纯手写代码自己用封装个Button。这个Button继承于UIView类,在封装的时候用上啦OC中的三种回调模式:目标动作回调,委托回调,Block回调。具体的内容请参考之前的博客:“Objective-C中的Block回调模式”,“Target-Action回调模式”,“Objective-C中的委托(代理)模式”。在接下来要封装的button中将要用到上面的知识点。之前在做新浪微博中的Cell的时候用到了Block回调来确定是那个Cell上的那个Button。

在封装Button之前呢,简单的了解一下UIView中的触摸事件:

1.当触摸开始时会调用下面的事件

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

2.当触摸取消时会调用下面的事件

-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event

3.当触摸结束时会调用下面的事件

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

4.当触摸移动时会调用下面的事件

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

所以在封装自己的button是我们会用上上面的方法,首先新建一个ViewController, 然后把我们新建的ViewController在AppDelegate.m中设置成我们的根视图,我们关于Button的初始化和配置都写在ViewController中的ViewDidLoad中代码如下:

1MyViewController *myViewController =[[MyViewController alloc] init];2self.window.rootViewController = myViewController;

一、目标动作回调:

首先新建一个MyButton类,MyButton类继承于UIView, 我们就在MyButton类中自定义我们的button.下面要为自定义Button添加目标动作回调接口,步骤如下:

1.在MyButton.h中声明目标动作注册方法:

//TargetAction回调-(void)addTarget:target action:(SEL)action;

2.在MyButton.m中进行实现:

1//延展2@interfaceMyButton()34@PRoperty (nonatomic,weak)idtarget;5@property (nonatomic, assign) SEL action;67@end8910//实现11@implementationMyButton12//目标动作回调13-(void)addTarget:(id)target action:(SEL)action14{15self.target =target;16self.action =action;17}

3.通过target来执行action方法,触摸完成的事件中让target执行action方法,执行之前要判断一下触摸的释放点是否在按钮的区域内,代码如下:

1//当button点击结束时,如果结束点在button区域中执行action方法2-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event3{4//获取触摸对象5UITouch *touche =[touches anyObject];6//获取touche的位置7CGPoint point =[touche locationInView:self];89//判断点是否在button中10if(CGRectContainsPoint(self.bounds, point))11{12//执行action13[self.target performSelector:self.action withObject:self];14}1516}

4.在MyViewController中进行button的初始化,并注册目标方法回调,当点击button时,我们MyViewController中的tapButton方法就会被执行:

1//在v2中添加一个button2MyButton *button = [[MyButton alloc] initWithFrame:CGRectMake(10,10,44,44)];34button.backgroundColor =[UIColor blackColor];56//注册回调7[button addTarget:self action:@selector(tapButton)];

二、委托回调

1.在上面的基础上添加上委托回调,通过委托回调添加按钮是否可用,按钮将要点击和按钮点击后的事件,首先我们得有协议来声明这三个方法。协议我们就不新建文件了,下面的协议是添加在MyButton.h中的,协议定义如下:

1//定义MyButton要实现的协议, 用于委托回调2@protocolMyButtonDelegete <NSObject>34//可选择的实现5@optional67//当button将要点击时调用8-(void) myButtonWillTap:(MyButton *) sender;910//当button点击后做的事情11-(void) myButtonDidTap: (MyButton *) sender;1213//判断button是否可以被点击14-(BOOL) myButtonShouldTap: (MyButton *) sender;1516@end

2.在MyButton.h中添加delegate属性,为了避免强引用循环,定义为weak类型,用于回调的注册:

//委托回调接口@property (nonatomic, weak)id<MyButtonDelegete>delegate;

3.在MyButton.m中当开始点击按钮时做一下处理,首先得判断delegate对象是否实现了协议中的方法如果实现了就通过delegate回调,如果没实现就不调用

2-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event3{45//判断myButtonShouldTap是否在degate中实现啦:委托回调6if([self.delegaterespondsToSelector:@selector(myButtonShouldTap:)])7{8//如果实现了,就获取button的状态9myButtonState = [self.delegatemyButtonShouldTap:self];1011}1213//根据按钮的状态来做处理14if(myButtonState)15{16//如果myButtonWillTap被实现啦,此时我们就实现myButtonWillTapf方法17if([self.delegaterespondsToSelector:@selector(myButtonWillTap:)])18{19[self.delegatemyButtonWillTap:self];20}21}22}

4.在touchesEnded中相应的位置添加如下代码去执行按钮点击时要回调的方法:

1//点击结束要调用myButtonDidTap 委托回调2if([self.delegaterespondsToSelector:@selector(myButtonDidTap:)])3{4[self.delegatemyButtonDidTap:self];5}

5、在MyViewController.m中注册委托回调

1//注册委托回调2button.delegate= self;

6、MyViewController要实现MyButtonDelegate,并实现相应的方法

1//实现button委托回调的方法myButtonShouldTap:设置button是否好用2-(BOOL) myButtonShouldTap:(MyButton *)sender3{4NSLog(@"我是Delegate:should方法");5returnYES;6}78//实现按钮将要点击的方法9-(void)myButtonWillTap:(MyButton *)sender10{11NSLog(@"我是Delegate: will方法");12}1314//实现按钮点击完要回调的方法15-(void) myButtonDidTap:(MyButton *)sender16{17NSLog(@"我是Delegate: Did");18}

三.Block回调

1、为我们的按钮添加Block回调(把上面的委托回调改成Block回调),和之前微博中的Cell的Block回调类似,首先在MyButton.h中声明我们要用的Block类型,然后提供Block的set方法:

//button中使用Block回调,定义Block类型@classMyButton;

typedefvoid(^ButtonWillAndDidBlock) (MyButton *sender);

typedef BOOL (^ButtonShouldBlock) (MyButton *sender);//接受block的方法-(void)setButtonShouldBlock: (ButtonShouldBlock) block;-(void)setButtonWillBlock: (ButtonWillAndDidBlock) block;-(void)setButtonDidBlock:(ButtonWillAndDidBlock) block;

2.在MyButton.m中的延展中添加相应的属性来接受Controller中传过来的Block

1//接受block块2@property (nonatomic, strong) ButtonWillAndDidBlock willBlock;3@property (nonatomic, strong) ButtonWillAndDidBlock didBlock;4@property (nonatomic, strong) ButtonShouldBlock shouldBlock;

3.实现setter方法

1//实现block回调的方法2-(void)setButtonWillBlock:(ButtonWillAndDidBlock)block3{4self.willBlock =block;5}67-(void)setButtonDidBlock:(ButtonWillAndDidBlock)block8{9self.didBlock =block;10}1112-(void) setButtonShouldBlock:(ButtonShouldBlock)block13{14self.shouldBlock =block;15}

4.在MyButton.m中有委托调用的地方加入相应的Block回调,添加的代码如下:

1//block回调2if(self.shouldBlock) {3//block回调获取按钮状态4myButtonState =self.shouldBlock(self);5}678//block回调实现willTap9if(self.willBlock)10{11self.willBlock(self);12}131415//block回调16if(self.didBlock) {17self.didBlock(self);18}

5、在MyViewController中调用Button中的setter方法传入相应的block:

12//实现button的block回调3[button setButtonShouldBlock:^BOOL(MyButton *sender) {4NSLog(@"我是Block: should方法\n\n");5returnYES;6}];78[button setButtonWillBlock:^(MyButton *sender) {9NSLog(@"我是Block: Will方法\n\n");10}];1112[button setButtonDidBlock:^(MyButton *sender) {13NSLog(@"我是Blcok: Did方法\n\n");14}];151617[self.view addSubview:button];

经过上面的代码我们的button就拥有三种回调模式了,下面是点击button控制台输出的日志:

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航