你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS開發- runtime基本用法解析和用runtime給鍵盤添加工具欄和按鈕響應事件

iOS開發- runtime基本用法解析和用runtime給鍵盤添加工具欄和按鈕響應事件

編輯:IOS開發綜合

1.如何用runtime給鍵盤添加工具欄和按鈕響應事件:

.h
#import 
#import 
@interface KeyBoardTool : NSObject


/**
 *  增加隱藏鍵盤按鈕
 *
 *  @param textfield 輸入框對象
 */
+ (void)hideKeyboard:(UITextField *)textfield;
@end



.m
#pragma mark - 增加隱藏鍵盤按鈕
+ (void)hideKeyboard:(UITextField *)textfield {
    //為鍵盤增加工具欄
    UIToolbar * topView = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, ScreenWidth, 40)];
    [topView setBarStyle:UIBarStyleDefault];
    [textfield setInputAccessoryView:topView];

    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
    btn.frame = CGRectMake(0, 5, 40, 30);
    [btn addTarget:self action:@selector(dismissKeyBoard:) forControlEvents:UIControlEventTouchUpInside];
    [btn setBackgroundImage:[UIImage imageNamed:@"closed"] forState:UIControlStateNormal];

    //將TextField綁定到button上,kTextField要和UITextField創建的對象名一致
     /*
     第一個參數是需要添加屬性的對象;
     第二個參數是屬性的key;
     第三個參數是屬性的值;
     第四個參數是一個枚舉值,類似@property屬性創建時設置的關鍵字,可從命名看出各含義
     */
    objc_setAssociatedObject(btn, kTextField, textfield, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    //UIBarButtonSystemItemFlexibleSpace自動調節按鈕間距
    UIBarButtonItem * leftBtn = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:self action:nil];
//如果希望左側顯示按鈕,重新實例化一個按鈕用 CustomView 方法設置,類似下面的rightBtn。  


    UIBarButtonItem *rightBtn = [[UIBarButtonItem alloc] initWithCustomView:btn];

    NSArray * buttonsArray = [NSArray arrayWithObjects:leftBtn,rightBtn,nil];

    [topView setItems:buttonsArray];
}

+ (void)dismissKeyBoard:(UIButton *)button{
    //獲取button上對應的屬性,kTextField要和UITextField創建的對象名一致
    [objc_getAssociatedObject(button, kTextField) resignFirstResponder];
}

其實這些都是固定的方法,一開始接觸綁定的方法看不懂,也沒什麼好理解的,記住就好。
2.獲取某一個類所有屬性和所有方法

+ (void)getAllPropertyAndAllMethod:(id)myClass
{
    unsigned int outCount = 0;
    // 獲取到所有的成員變量列表
    Ivar *vars = class_copyIvarList([myClass class], &outCount);
    // 遍歷所有的成員變量
    for (int i = 0; i < outCount; i++) {
        Ivar ivar = vars[i]; // 取出第i個位置的成員變量

        const char *propertyName = ivar_getName(ivar); // 獲取變量名
        const char *propertyType = ivar_getTypeEncoding(ivar); // 獲取變量編碼類型
        printf("%s/%s\n", propertyName, propertyType);

    }


    unsigned int count;
    //獲取方法列表,所有在.m文件顯式實現的方法都會被找到,包括setter+getter方法;
    Method *allMethods = class_copyMethodList([myClass class], &count);
    for(int i =0;i<count;i++) char="" const="" md="allMethods[i];" method="" methodname="sel_getName(sel);" pre="" sel="">

通過以上方法可以看到許多隱藏的屬性和方法,但是,請慎用,比較常用的方法有設置placeholder的字體大小:

    [_loginTestField setValue:[UIFont systemFontOfSize:14] forKeyPath:@"_placeholderLabel.font"];

3.改變屬性值

+ (void)changeVariable
{
    ViewController *viewVC = [[ViewController alloc]init];
    NSLog(@"改變前的viewVC:%@",viewVC);

    unsigned int count = 0;
    Ivar *vars = class_copyIvarList([ViewController class], &count);

    Ivar ivv = vars[0]; //從第一個方法getAllVariable中輸出的控制台信息,我們可以看到實例屬性。
    object_setIvar(viewVC, ivv, @"world"); //屬性被強制改為world。

    NSLog(@"改變之後的viewVC:%@",viewVC);

}

從上面方法中能看出來改變的是ViewController中第一個實例屬性的值。

4.增加新方法

+ (void)addNewMethod
{
    /* 動態添加方法:
     第一個參數表示Class cls 類型;
     第二個參數表示待調用的方法名稱;
     第三個參數(IMP)myAddingFunction,IMP一個函數指針,這裡表示指定具體實現方法myAddingFunction;
     第四個參數表方法的參數,0代表沒有參數;
     */
    ViewController *viewVC = [[ViewController alloc]init];

    class_addMethod([viewVC class], @selector(myNewMethod), (IMP)addingMethod, 0);
    //調用方法
    [viewVC performSelector:@selector(myNewMethod)];
}
//這個方法不調用,但是不寫的話會報警告
- (void)myNewMethod
{

}
//具體的實現(方法的內部都默認包含兩個參數Class類和SEL方法,被稱為隱式參數。)
int addingMethod(id self, SEL _cmd){
    NSLog(@"已新增方法:myNewMethod");

    return 1;
}

5.交換方法

+ (void)exchangeMethod
{
    ViewController *viewVC = [[ViewController alloc]init];

    Method method1 = class_getInstanceMethod([viewVC class], @selector(method1));
    Method method2 = class_getInstanceMethod([viewVC class], @selector(method2));

    //交換方法
    method_exchangeImplementations(method1, method2);

    [viewVC method1];
}

在ViewController中有method1和method2兩個方法,method_exchangeImplementations交換了這兩個方法,所以當調用method1,實際上調用的是method2.

6.增加新屬性 假如要給ViewController添加新屬性,先創建一個繼承於ViewController的category,然後下面看代碼:

.h
#import "ViewController.h"

@interface ViewController (VVC)

@property (nonatomic,strong)NSString *vccVariable;


@end


.m
#import "ViewController+VVC.h"
#import  //runtime API的使用需要包含此頭文件

const char * vcc = "vcckey"; //做為key,字符常量 必須是C語言字符串;
@implementation ViewController (VVC)


-(void)setVccVariable:(NSString *)vccVariable{

    NSString *newStr = [NSString stringWithFormat:@"%@",vccVariable];
    /*
     第一個參數是需要添加屬性的對象;
     第二個參數是屬性的key;
     第三個參數是屬性的值;
     第四個參數是一個枚舉值,類似@property屬性創建時設置的關鍵字,可從命名看出各含義
     */
    objc_setAssociatedObject([ViewController class],vcc, newStr, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

//提取屬性的值:
-(NSString *)vccVariable{
    NSString *myVccVariable = objc_getAssociatedObject([ViewController class], vcc);
    return myVccVariable;
}


@end

Demo下載地址:https://github.com/codeliu6572/Runtime_use 學習runtime,也許看起來不是很好懂,就好比我們剛學習一門新的語言,我們從沒見過這樣的代碼,最簡單的方法就是記住,但是對於runtime,用得好的話能夠省很多事,用不好的後果可能會被蘋果拒絕,甚至說根本駕馭不了,博主這裡只是淺層次的運用,每一門語言都博大精深,需要認真去研究。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved