有時(shí)在項(xiàng)目中需要對(duì)一些類進(jìn)行擴(kuò)展檩淋,Apple又只提供了對(duì)方法的擴(kuò)展牵咙,對(duì)屬性的擴(kuò)展只能使用runtime機(jī)制派近,對(duì)分類進(jìn)行屬性擴(kuò)展。廢話不多說洁桌,直接上代碼:
UIViewController+Information.h文件
#import <UIKit/UIKit.h>
@interface UIViewController (Information)
@property (nonatomic, copy) NSString *name; //視圖名字
@property (nonatomic, assign) BOOL hasChildViewController; //是否有子視圖
@property (nonatomic, strong) UIImage *backgroundImage; //背景圖片@end
再來看看其實(shí)現(xiàn):
UIViewController+Information.m文件
#import "UIViewController+Information.h"
#import <objc/runtime.h>
static const void *kName = "name";
static const void *kHasChildViewController = @"hasChildViewController";
static const void *kBackgroundImage = @"backgroundImage";
@implementation UIViewController (Information)
#pragma mark - 字符串類型的動(dòng)態(tài)綁定
- (NSString *)name { return objc_getAssociatedObject(self, kName);}
- (void)setName:(NSString *)name {
objc_setAssociatedObject(self, kName, name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
#pragma mark - BOOL類型的動(dòng)態(tài)綁定
- (BOOL)hasChildViewController {
return [objc_getAssociatedObject(self, kHasChildViewController) boolValue];
}
- (void)setHasChildViewController:(BOOL)hasChildViewController {
objc_setAssociatedObject(self, kHasChildViewController, [NSNumber numberWithBool:hasChildViewController], OBJC_ASSOCIATION_ASSIGN);
}
#pragma mark - 類類型的動(dòng)態(tài)綁定
- (UIImage *)backgroundImage {
return objc_getAssociatedObject(self, kBackgroundImage);
}
- (void)setBackgroundImage:(UIImage *)backgroundImage {
objc_setAssociatedObject(self, kBackgroundImage, backgroundImage, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
然后我們就可以引入這個(gè)頭文件渴丸,對(duì)UIViewController進(jìn)行了3個(gè)屬性(name, hasChildViewController, backgroundImage)的擴(kuò)展。
下面來個(gè)實(shí)際的應(yīng)用,給鍵盤添加一個(gè)縮回的按鈕谱轨,以UITextField為例戒幔,原理如下:
給鍵盤添加ToolBar, ToolBar上有一個(gè)具有縮回功能的button
將UITextField綁定到這個(gè)button上
添加縮回的方法土童,在方法中通過button獲取這個(gè)UITextField诗茎,調(diào)用這個(gè)UITextField的resignFirstResponder方法即可
定義一個(gè)工具類來隱藏鍵盤
YQTool.h文件
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface YQTool : NSObject
#pragma mark - 增加隱藏鍵盤按鈕
+ (void)hideKeyboard:(UITextField *)textfield;
@end
YQTool.m文件
#import "YQTool.h"
#import <objc/runtime.h>
//獲取屏幕寬度的宏
#define ScreenWidth ([[UIScreen mainScreen] bounds].size.width)
static const void *kTextField = "textField";
@implementation YQTool
#pragma mark - 增加隱藏鍵盤按鈕
+ (void)hideKeyboard:(UITextField *)textfield {
//為鍵盤增加工具欄
UIToolbar * topView = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, ScreenWidth, 30)];
[topView setBarStyle:UIBarStyleDefault];
UIBarButtonItem * btnSpace = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(2, 5, 50, 25);
//將TextField綁定到button上
objc_setAssociatedObject(btn, kTextField, textfield, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[btn addTarget:self action:@selector(dismissKeyBoard:) forControlEvents:UIControlEventTouchUpInside];
[btn setBackgroundImage:[UIImage imageNamed:@"closed"] forState:UIControlStateNormal];
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithCustomView:btn];
NSArray * buttonsArray = [NSArray arrayWithObjects:btnSpace,doneBtn,nil];
[topView setItems:buttonsArray];
[textfield setInputAccessoryView:topView];
}
+ (void)dismissKeyBoard:(UIButton *)button{
//獲取button上對(duì)應(yīng)的屬性
[objc_getAssociatedObject(button, kTextField) resignFirstResponder];
}
@end
在需要縮回的按鈕中,使用一行代碼就在鍵盤上展示縮回的按鈕:
[YQTool hideKeyboard:_nameTextField];
效果圖如下:
效果圖
12-16
最近看到一個(gè)比較好的寫法記錄下:
- (BOOL)wl_useDefaultBackButton{
NSNumber *number = objc_getAssociatedObject(self, _cmd);
if (number) {
return number.boolValue;
}
self.wl_useDefaultBackButton = NO;
return YES;
}
- (void)setWl_useDefaultBackButton:(BOOL)wl_useDefaultBackButton{
SEL key = @selector(wl_useDefaultBackButton);
objc_setAssociatedObject(self, key, @(wl_useDefaultBackButton), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}