介绍
- dynamicWebkit替换、
- 动态添加方法 + 动态交换方法 -> UIButton防止多次点击、
- 遍历变量 -> 隐藏键盘、
- 遍历属性 -> 获取属性名
- 遍历属性 -> 判断所有变量是否已经实例化
dynamicWebkit
Apple 从 iOS8 开始,推出了更新、优化更好的WKWebkit。这个库是UIWebView的继承者,在相同的浏览页面下,WKWebKit提供的WKWebView的内存占用率甚至可以只有UIWebView的1/10。可惜的是,我们很多时候为了保证用户的覆盖率,target iOS Version都是 iOS7。这时候我们就需要使用UIWebView来达到显示的目的。
那么问题来了,如何实现根据iOS版本来达到动态加载的目的呢?
参考 http://www.jianshu.com/p/3f71fb190fbe
感觉这更多是偏向于URL route的感觉,类似的还有:
http://www.jianshu.com/p/8b3a9155468d
步骤:
- 新建UIButton分类,在load方法中 使用自定义方法替换掉原先的
- (void)sendAction:(SEL)action to:(nullable id)target forEvent:(nullable UIEvent *)event
方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| + (void)load { SEL originSEL = @selector(sendAction:to:forEvent:); SEL mySEL = @selector(my_sendAction:to:forEvent:); Method originM = class_getInstanceMethod([self class], originSEL); const char *typeEncodinds = method_getTypeEncoding(originM); Method newM = class_getInstanceMethod([self class], mySEL); IMP newIMP = method_getImplementation(newM); if (class_addMethod([self class], mySEL, newIMP, typeEncodinds)) { class_replaceMethod([self class], originSEL, newIMP, typeEncodinds); } else { method_exchangeImplementations(originM, newM); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| - (void)my_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event { if ([self isKindOfClass:[UIButton class]]) { self.clickDurationTime = self.clickDurationTime == 0 ? defaultDuration : self.clickDurationTime; if (_isIgnoreEvent) { NSLog(@" 忽略按钮事件 "); return; } else if(self.clickDurationTime > 0) { NSLog(@"//2.2 不忽略按钮事件"); _isIgnoreEvent = YES; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.clickDurationTime * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ resetState(); }); [self my_sendAction:action to:target forEvent:event]; } } else { [self my_sendAction:action to:target forEvent:event]; } }
|
遍历变量 -> 隐藏键盘
在viewcontroller中有些操作需要隐藏原先的键盘
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
+(void)resignTFandTV:(id)obj{ unsigned int outCount = 0; Ivar *vars = class_copyIvarList([obj class], &outCount); for (int i = 0; i < outCount; i ++) { Ivar var = vars[i]; const char *name = ivar_getName(var); NSString *key = [NSString stringWithUTF8String:name];
id value = [obj valueForKey:key]; if ([value isKindOfClass:[UITextField class]] || [value isKindOfClass:[UITextView class]]) { if([value canResignFirstResponder]) [value resignFirstResponder]; } } }
|
遍历属性 -> 获取属性名
一些简单的model 或者自定义 view ,可以获取属性名来实例化对应的属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
+(NSMutableArray<NSString*>*)getIvarNamesFrom:(id)obj specialCls:(Class)aClass{ NSMutableArray<NSString*>* arr = [NSMutableArray arrayWithCapacity:0]; unsigned int outCount = 0; objc_property_t *properties = class_copyPropertyList([obj class], &outCount); for (int i = 0; i < outCount; i ++) { objc_property_t property = properties[i]; NSString* name = [self getProertyIvarName:property]; NSString* type = [self getProertyTypeName:property]; if(aClass){ if(type){ Class someClass = NSClassFromString(type); if(someClass && someClass == aClass ){ if(name) [arr addObject:name]; } } } else{ if(name) [arr addObject:name]; } } free(properties); return arr; }
+(NSString*)getProertyIvarName:(objc_property_t)property{ unsigned int count = 0; objc_property_attribute_t *attrbutes = property_copyAttributeList(property, &count); for (unsigned int j = 0; j < count; ++j) { objc_property_attribute_t attribute = attrbutes[j]; const char *name = attribute.name; const char *value = attribute.value; NSString *utfName = [NSString stringWithUTF8String:name]; NSString *utfValue = [NSString stringWithUTF8String:value]; if([utfName isEqualToString:@"V"]){ utfValue = [utfValue stringByReplacingOccurrencesOfString:@"\"" withString:@""]; utfValue = [utfValue stringByReplacingOccurrencesOfString:@"@" withString:@""]; return utfValue; } } free(attrbutes); return nil; }
+(NSString*)getProertyTypeName:(objc_property_t)property{ unsigned int count = 0; objc_property_attribute_t *attrbutes = property_copyAttributeList(property, &count); for (unsigned int j = 0; j < count; ++j) { objc_property_attribute_t attribute = attrbutes[j]; const char *name = attribute.name; const char *value = attribute.value; NSString *utfName = [NSString stringWithUTF8String:name]; NSString *utfValue = [NSString stringWithUTF8String:value]; if([utfName isEqualToString:@"T"]){ utfValue = [utfValue stringByReplacingOccurrencesOfString:@"\"" withString:@""]; utfValue = [utfValue stringByReplacingOccurrencesOfString:@"@" withString:@""]; return utfValue; } } free(attrbutes); return nil; }
|
遍历属性 -> 判断所有变量是否已经实例化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
+(BOOL)isIvarsVaildOf:(id)obj specialCls:(Class)aClass{ NSMutableArray<NSString*>* ivarNames = [self getIvarNamesFrom:self specialCls:aClass]; for(int i = 0 ; i < ivarNames.count; i++){ NSString* key = ivarNames[i]; id value = [obj valueForKey:key]; if(!value) return false; } return true; }
+(BOOL)isIvarAllVaildOf:(id)obj{ return [self isIvarsVaildOf:obj specialCls:nil]; }
|