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

  前面在做东西的时候都用到了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中代码如下:

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

  一、目标动作回调:

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

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

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

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

 1 //延展
 2 @interface MyButton()
 3
 4 @property (nonatomic,weak) id target;
 5 @property (nonatomic, assign) SEL action;
 6
 7 @end
 8
 9
10 //实现
11 @implementation MyButton
12 //目标动作回调
13 -(void)addTarget:(id)target action:(SEL)action
14 {
15     self.target = target;
16     self.action = action;
17 }

  

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

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

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

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

  二、委托回调 

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

 1 //定义MyButton要实现的协议, 用于委托回调
 2 @protocol MyButtonDelegete <NSObject>
 3
 4 //可选择的实现
 5 @optional
 6
 7 //当button将要点击时调用
 8 -(void) myButtonWillTap:(MyButton *) sender;
 9
10 //当button点击后做的事情
11 -(void) myButtonDidTap: (MyButton *) sender;
12
13 //判断button是否可以被点击
14 -(BOOL) myButtonShouldTap: (MyButton *) sender;
15
16 @end

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

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

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

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

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

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

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

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

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

 1 //实现button委托回调的方法myButtonShouldTap:设置button是否好用
 2 -(BOOL) myButtonShouldTap:(MyButton *)sender
 3 {
 4     NSLog(@"我是Delegate:should方法");
 5     return YES;
 6 }
 7
 8 //实现按钮将要点击的方法
 9 -(void)myButtonWillTap:(MyButton *)sender
10 {
11     NSLog(@"我是Delegate: will方法");
12 }
13
14 //实现按钮点击完要回调的方法
15 -(void) myButtonDidTap:(MyButton *)sender
16 {
17     NSLog(@"我是Delegate: Did");
18 }

  三.Block回调

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

//button中使用Block回调,定义Block类型
@class MyButton;
typedef void (^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)block
 3 {
 4     self.willBlock = block;
 5 }
 6
 7 -(void)setButtonDidBlock:(ButtonWillAndDidBlock)block
 8 {
 9     self.didBlock = block;
10 }
11
12 -(void) setButtonShouldBlock:(ButtonShouldBlock)block
13 {
14     self.shouldBlock = block;
15 }

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

 1     //block回调
 2     if (self.shouldBlock) {
 3         //block回调获取按钮状态
 4         myButtonState = self.shouldBlock(self);
 5     }
 6
 7
 8         //block回调实现willTap
 9         if (self.willBlock)
10         {
11             self.willBlock(self);
12         }
13
14
15         //block回调
16         if (self.didBlock) {
17             self.didBlock(self);
18         }

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

 1
 2     //实现button的block回调
 3     [button setButtonShouldBlock:^BOOL(MyButton *sender) {
 4         NSLog(@"我是Block: should方法\n\n");
 5         return YES;
 6     }];
 7
 8     [button setButtonWillBlock:^(MyButton *sender) {
 9         NSLog(@"我是Block: Will方法\n\n");
10     }];
11
12     [button setButtonDidBlock:^(MyButton *sender) {
13         NSLog(@"我是Blcok: Did方法\n\n");
14     }];
15
16
17     [self.view addSubview:button];

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

时间: 2024-11-04 12:24:15

IOS开发之自定义Button(集成三种回调模式)的相关文章

iOS开发 跳转场景的三种方式

假设A跳转到B,三种方法: 1.按住ctrl键,拖动A上的控件(比如说UIButton)到B上,弹出菜单,选择Modal.不需要写任何代码,在A上点击Button就会跳转到B 2. 按住ctrl键,拖动A上的View Controller到B上,弹出菜单,选择Modal,两个场景间自动添加连接线和图标,选中该图标,打开Storyboard Segue,identifier输入一个标识符,这里以”aaaa”为例.A里需要跳转时,执行下面的代码: 1 [self performSegueWithId

ios开发日记11 对tableView三种计算动态行高方法的分析

tableView是一个神奇的东西,可以这么说,就算是一个初学者如果能把tableView玩的很6,那编一般的iOS的需求都问题不大了.tableView是日常开发中用烂了的控件,但是关于tableView中的自定义cell的动态行高,还是有一些玄机的. AD: tableView是一个神奇的东西,可以这么说,就算是一个初学者如果能把tableView玩的很6,那编一般的iOS的需求都问题不大了.tableView是日常开发中用烂了的控件,但是关于tableView中的自定义cell的动态行高,

EBS OAF 开发中的OAQueryBean的三种构造模式

EBS OAF 开发中的OAQueryBean的构造模式 (版权声明,本人原创或者翻译的文章如需转载,如转载用于个人学习,请注明出处:否则请与本人联系,违者必究) 当你为pageLayout区域添加一个query 区域时,OAF框架生成一个oracle.apps.fnd.framework.webui.beans.layout.OAQueryBean对象,它依赖于它的配置,并通过一个子控件table, advanced table或者HGrid来实现simple search, advanced

iOS_Swift初识之使用三种回调方式自定义Button

最近在学习Swift ,发现青玉伏案大神早期用OC写的一篇博客--IOS开发之自定义Button(集成三种回调模式)  很适合用来熟悉Swift的回调方式,于是我就用Swift翻版了一下,具体实现原理就不多说了,主要贴上Swift的代码给大家看看.由于刚开始了解Swift,有使用不恰当的地方请轻拍.... 上代码: 1.新建一个xib,拖一个UIView到界面上,绑定上自定义的UIView类,拖一个UILabel到view上,写上Button假装是个UIButton:并将label拖到代码当中

iOS开发之自定义表情键盘(组件封装与自动布局)

下面的东西是编写自定义的表情键盘,话不多说,开门见山吧!下面主要用到的知识有MVC, iOS开发中的自动布局,自定义组件的封装与使用,Block回调,CoreData的使用.有的小伙伴可能会问写一个自定义表情键盘肿么这么麻烦?下面将会介绍我们如何用上面提到的东西来定义我们的表情键盘的.下面的内容会比较多,这篇博文还是比较有料的. 还是那句话写技术博客是少不了代码的,下面会结合代码来回顾一下iOS的知识,本篇博文中用到的知识点在前面的博客中都能找到相应的内容,本篇算是一个小小的功能整合.先来张图看

iOS开发UI篇—Button基础

iOS开发UI篇—Button基础 一.简单说明 一般情况下,点击某个控件后,会做出相应反应的都是按钮 按钮的功能比较多,既能显示文字,又能显示图片,还能随时调整内部图片和文字的位置 二.按钮的三种状态 normal(普通状态) 默认情况(Default) 对应的枚举常量:UIControlStateNormal highlighted(高亮状态) 按钮被按下去的时候(手指还未松开) 对应的枚举常量:UIControlStateHighlighted disabled(失效状态,不可用状态) 如

iOS开发之动画编程的几种方法

iOS开发之动画编程的几种方法 IOS中的动画总结来说有五种:UIView<block>,CAAnimation<CABasicAnimation,CATransition,CAKeyframeAnimation>,NSTimer 这里我就总结了一下这五种方法,其实iOS开发中动画的编程都会在这里面变化,所以只要弄懂了这些动画编程就不难了. 一:UIView动画 一般方式 [UIView beginAnimations:@"ddd" context:nil];/

实现自定义View的三种方式

一.组合控件 组合控件,顾名思义,就是将系统原有的控件进行组合,构成一个新的控件.这种方式下,不需要开发者自己去绘制图上显示的内容,也不需要开发者重写onMeasure,onLayout,onDraw方法来实现测量.布局以及draw流程.所以,在实现自定义view的三种方式中,这一种相对比较简单. 实际开发中,标题栏就是一个比较常见的例子.因为在一个app的各个界面中,标题栏基本上是大同小异,复用率很高.所以经常会将标题栏单独做成一个自定义view,在不同的界面直接引入即可,而不用每次都把标题栏

IOS开发中数据持久化的几种方法--NSUserDefaults

IOS开发中数据持久化的几种方法--NSUserDefaults IOS 开发中,经常会遇到需要把一些数据保存在本地的情况,那么这个时候我们有以下几种可以选择的方案: 一.使用NSUserDefault是最简单直接的一个办法: 1)保存数据: 1 // 实例化一个NSUserDefaults单例对象 2 NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; 3 // 把一个数组array保存在key为allContact的键值