前面在做東西的時候都用到了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中進行實現:
//延展
@interface MyButton()@property (nonatomic,weak) id target;
@property (nonatomic, assign) SEL action;@end//實現
@implementation MyButton
//目標動作回調
-(void)addTarget:(id)target action:(SEL)action
{self.target = target;self.action = action;
}
3.通過target來執行action方法,觸摸完成的事件中讓target執行action方法,執行之前要判斷一下觸摸的釋放點是否在按鈕的區域內,代碼如下:
//當button點擊結束時,如果結束點在button區域中執行action方法
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{//獲取觸摸對象UITouch *touche = [touches anyObject];//獲取touche的位置CGPoint point = [touche locationInView:self];//判斷點是否在button中if (CGRectContainsPoint(self.bounds, point)){//執行action[self.target performSelector:self.action withObject:self]; }}
?
4.在MyViewController中進行button的初始化,并注冊目標方法回調,當點擊button時,我們MyViewController中的tapButton方法就會被執行:
//在v2中添加一個buttonMyButton *button = [[MyButton alloc] initWithFrame:CGRectMake(10, 10, 44, 44)];button.backgroundColor = [UIColor blackColor];//注冊回調[button addTarget:self action:@selector(tapButton)];
?
二、委托回調
1.在上面的基礎上添加上委托回調,通過委托回調添加按鈕是否可用,按鈕將要點擊和按鈕點擊后的事件,首先我們得有協議來聲明這三個方法。協議我們就不新建文件了,下面的協議是添加在MyButton.h中的,協議定義如下:
//定義MyButton要實現的協議, 用于委托回調
@protocol MyButtonDelegete <NSObject>//可選擇的實現
@optional//當button將要點擊時調用
-(void) myButtonWillTap:(MyButton *) sender;//當button點擊后做的事情
-(void) myButtonDidTap: (MyButton *) sender;//判斷button是否可以被點擊
-(BOOL) myButtonShouldTap: (MyButton *) sender;@end
?
2.在MyButton.h中添加delegate屬性,為了避免強引用循環,定義為weak類型,用于回調的注冊:
//委托回調接口
@property (nonatomic, weak) id <MyButtonDelegete> delegate;
?
3.在MyButton.m中當開始點擊按鈕時做一下處理,首先得判斷delegate對象是否實現了協議中的方法如果實現了就通過delegate回調,如果沒實現就不調用
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{//判斷myButtonShouldTap是否在degate中實現啦:委托回調if ([self.delegate respondsToSelector:@selector(myButtonShouldTap:)]){//如果實現了,就獲取button的狀態myButtonState = [self.delegate myButtonShouldTap:self];} //根據按鈕的狀態來做處理if (myButtonState){//如果myButtonWillTap被實現啦,此時我們就實現myButtonWillTapf方法if ([self.delegate respondsToSelector:@selector(myButtonWillTap:)]){[self.delegate myButtonWillTap:self];}}
}
?
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,并實現相應的方法
//實現button委托回調的方法myButtonShouldTap:設置button是否好用
-(BOOL) myButtonShouldTap:(MyButton *)sender
{NSLog(@"我是Delegate:should方法");return YES;
}//實現按鈕將要點擊的方法
-(void)myButtonWillTap:(MyButton *)sender
{NSLog(@"我是Delegate: will方法");
}//實現按鈕點擊完要回調的方法
-(void) myButtonDidTap:(MyButton *)sender
{NSLog(@"我是Delegate: Did");
}
?
三.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方法
//實現block回調的方法
-(void)setButtonWillBlock:(ButtonWillAndDidBlock)block
{self.willBlock = block;
}-(void)setButtonDidBlock:(ButtonWillAndDidBlock)block
{self.didBlock = block;
}-(void) setButtonShouldBlock:(ButtonShouldBlock)block
{self.shouldBlock = block;
}
?
4.在MyButton.m中有委托調用的地方加入相應的Block回調,添加的代碼如下:
//block回調if (self.shouldBlock) {//block回調獲取按鈕狀態myButtonState = self.shouldBlock(self);}//block回調實現willTapif (self.willBlock){self.willBlock(self);}//block回調if (self.didBlock) {self.didBlock(self);}
?
5、在MyViewController中調用Button中的setter方法傳入相應的block:
//實現button的block回調[button setButtonShouldBlock:^BOOL(MyButton *sender) {NSLog(@"我是Block: should方法\n\n");return YES;}];[button setButtonWillBlock:^(MyButton *sender) {NSLog(@"我是Block: Will方法\n\n");}];[button setButtonDidBlock:^(MyButton *sender) {NSLog(@"我是Blcok: Did方法\n\n");}];[self.view addSubview:button];
經過上面的代碼我們的button就擁有三種回調模式了,下面是點擊button控制臺輸出的日志:
?
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀
總結
以上是生活随笔為你收集整理的IOS开发之自定义Button(集成三种回调模式)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。