寫在後面
在IOS開發中,時常會用到按鈕,經過按鈕的點擊來完成界面的跳轉等功用。按鈕事情的完成方式有多種,其中較為常用的是目的-舉措對形式。但這種方式使得view與controller之間的耦合水平較高,不引薦運用;
另一種方式是代理方式,按鈕的事情在view中綁定,controller作為view的代理完成代理辦法。
目的-舉措對完成方式
詳細來說,假定我們有一個包括一個Button的veiw,view將Button放在頭文件中,以便內部訪問。然後controller將view作為自己的view,在viewcontroller中完成按鈕的點擊事情。文字描繪起來仿佛不夠直觀,直接上代碼
1、MyView.h
包括一個可被內部訪問的按鈕的view
@interface MyView : UIView @property (strong, nonatomic) UIButton *myBtn; @end
2、MyView.m
#import "MyView.h" @implementation MyView //view的初始化辦法 - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { //初始化按鈕 _myBtn = [[UIButton alloc] initWithFrame:CGRectMake(140, 100, 100, 50)]; _myBtn.backgroundColor = [UIColor redColor]; //將按鈕添加到本身 [self addSubview:_myBtn]; } return self; } @end
3、MyViewController.h
#import <UIKit/UIKit.h> @interface MyViewController : UIViewController @end
4、MyViewController.m
添加MyView作為本身view
#import "MyViewController.h" #import "MyView.h" @interface MyViewController () @property (strong, nonatomic) MyView *myview; @end @implementation MyViewController - (void)loadView { MyView *myView = [[MyView alloc] initWithFrame: [[UIScreen mainScreen] bounds] ]; self.view = myView; self.myview = myView; //在controller中設置按鈕的目的-舉措,其中目的是self,也就是控制器本身,舉措是用目的提供的BtnClick:辦法, [self.myview.myBtn addTarget:self action:@selector(BtnClick:) forControlEvents:UIControlEventTouchUpInside]; } //MyView中的按鈕的事情 - (void)BtnClick:(UIButton *)btn { NSLog(@"Method in controller."); NSLog(@"Button clicked."); }
5、 AppDelegate.m
#import "AppDelegate.h" #import "MyViewController.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.Window = [ [UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds ] ]; MyViewController *myVC = [[MyViewController alloc] init]; self.Window.rootViewController = myVC; self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; return YES; }
6、運轉後果
界面:
輸入:
7、小結
這種將view中的屬性暴露在頭文件中的方式在一定水平上毀壞了封裝性。由於一旦將屬性暴露在頭文件中,內部任何包括該view的類能夠在不知情的狀況下修正了屬性,這不契合代碼高內聚、低耦合的開發要求,因而不引薦這種編寫按鈕事情的方式。
代理監聽按鈕事情
運用代理監聽按鈕事情的思緒是:不暴露view中的按鈕,而是為按鈕創立一個代理,在view頭文件中聲明一個代理,然後讓controller成為view的代理,並完成代理辦法,在view中回調controller中的回調辦法,從而完成按鈕事情。詳細代碼如下:
1、MyView.h -- 不再將按鈕暴露在頭文件中
在頭文件中聲明一個協議,協議也可以寫在獨自的文件中,然後經過import導入。
#import <UIKit/UIKit.h> //自定義的按鈕協議,該協議完成了<NSObject>協議,協議的稱號自定,不過不要和Apple的協議重名 @protocol myBtnDelegate <NSObject> //協議中的辦法,遵照該協議的類提供其詳細的完成,協議有@optional和@required兩個修飾符,默許狀況下是@required - (void) BtnClick:(UIButton *)btn; @end //MyView的接口 @interface MyView : UIView //聲明一個屬性,這個屬性用於指定誰來成為本類的代理,由於不能確定什麼類型的對象會成為本類的代理,因而聲明為id類型 @property (weak, nonatomic) id<myBtnDelegate> delegate; @end
2、MyView.m
按鈕被封裝在.m文件中,同時在.m文件中提供一個本中央法,在本中央法中調用代理的代理辦法
#import "MyView.h" @interface MyView () //聲明在.m中的按鈕對內部不可見 @property (strong, nonatomic) UIButton *myBtn; @end @implementation MyView //初始化 - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { _myBtn = [[UIButton alloc] initWithFrame:CGRectMake(140, 100, 100, 50)]; _myBtn.backgroundColor = [UIColor redColor]; //為按鈕設置目的-舉措,其中目的是self即包括該按鈕的view本身,舉措是有目的(view)提供的myBtnClick:辦法 [_myBtn addTarget:self action:@selector(myBtnClick:) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:_myBtn]; } return self; } //view中按鈕的事情 - (void)myBtnClick:(UIButton *)btn { NSLog(@"Method in view"); //在回調代理辦法時,首先判別本身的代理能否完成了代理辦法,否則會招致解體 //假如本身代理完成了代理辦法,在該辦法中回調代理完成的詳細的代理辦法 if ( [self.delegate respondsToSelector:@selector(BtnClick:)] ) { [self.delegate BtnClick: btn]; } else { NSLog(@"BtnClick: haven't found in delegate."); } } @end
3、MyViewController.h
同上(目的-舉措對完成方式)
4、MyViewController.m
#import "MyViewController.h" #import "MyView.h" //聲明該controller遵照 <myBtnDelegate>協議,因而需求完成協議中的辦法 @interface MyViewController () <myBtnDelegate> @end @implementation MyViewController - (void)loadView { //創立MyView類型的myView MyView *myView = [[MyView alloc] initWithFrame: [[UIScreen mainScreen] bounds] ]; //將myView的代理設置為self,即以後controller本身 myView.delegate = self; //將controller的view指向myView self.view = myView; } //該辦法是代理中的辦法,在controller中決議點擊myBtn按鈕後詳細要做的事情,但controller並不能直接獲取到myBtn - (void)BtnClick:(UIButton *)btn { NSLog(@"Method in controller."); NSLog(@"Button clicked."); }
5、AppDelegate
同上(目的-舉措對完成方式)
6、運轉後果
界面同上
日志:
7、小結
從日志可以看出,使controller成為view的代理,完成按鈕的代理辦法,與按鈕相關的辦法的執行順序為:view中按鈕的舉措辦法->controller提供的按鈕代理辦法。
現實上,在代理形式中,有三個角色存在:
協議:普通是辦法列表,規則了代理單方行為,在本例中 就是協議; 代理:遵照一定的協議的類,需求完成協議中的必需辦法,完成委托方的功用,本例中MyViewController就是代理; 委托:擁有自己的代理,指定代理去完成功用,本例中的MyView就是委托。代理形式用大白話說就是:委托方讓代理方替代自己執行一定的舉措。
總結
IOS中,類不能多承繼,但協議是可以多承繼的。協議並不提供詳細完成。協議普通是一系列辦法的集合,(也可以有屬性,但這不是協議的次要運用場景),這有點像Java中的接口,承繼接口的類擔任提供接口中辦法的詳細完成。
代理形式在IOS開發中運用的中央有很多,代理形式可以完成view和controller之間的解耦。拿本文中的例子來說,controller雖然可以操作view中按鈕點擊後的操作,但由於按鈕是作為view的公有屬性聲明在view的完成文件中的,因而controller並不知道view中有按鈕這個屬性的存在,因而無法從view內部去更改按鈕的各屬性,這就是view和controller之間解耦的表現。此外,由於按鈕事情是在view中綁定的,而不是在controller中綁定的,因而運用該view的類只需求完成相應的代理辦法就可以定制按鈕點擊後的事情了,這也愈加方便了view的復用,表現了view與controller解耦合的優勢。
以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支持本站。
【詳解iOS中按鈕點擊事情處置方式】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!