iOS开发 项目总结
1、UIButton点击事件用block代替
添加UIButton分类,在分类中添加如下代码
在.h文件中添加
typedef void (^ClickButtonBlock)(UIButton *button);
/**
将Block点击属性与点击事件进行关联
@param aEvent UIControlEvents
@param block 点击事件
*/
- (void)handleClickEvent:(UIControlEvents) aEvent usingBlock:(ClickButtonBlock)block;
在.m文件中添加
#import <objc/runtime.h>
static char *overViewKey;
- (void)handleClickEvent:(UIControlEvents)aEvent usingBlock:(ClickButtonBlock)block {
objc_setAssociatedObject(self, &overViewKey, block, OBJC_ASSOCIATION_COPY_NONATOMIC);
// 给button增加点击事件
[self addTarget:self action:@selector(buttonClicked:) forControlEvents:aEvent];
}
- (void)buttonClicked:(UIButton *)sender {
ClickButtonBlock clickedBlock = objc_getAssociatedObject(self, &overViewKey);
// 如果block存在则调用Blcok
if (clickedBlock != nil) {
clickedBlock(sender);
}
}
用到了runtime的objc_setAssociatedObject(关联)
函数
void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
参数说明
id object :表示关联者,是一个对象,变量名理所当然也是object
const void *key :获取被关联者的索引key
id value :被关联者,这里是一个block
objc_AssociationPolicy policy :关联时采用的协议,有assign,retain,copy等协议
调用
[collectionBtn handleClickEvent:UIControlEventTouchUpInside usingBlock:^(UIButton *button) {
//点击事件
}];
好处
1、在写项目时候不用写一堆全局变量来传参,block可以捕获局部变量到block内部直接用
2、不用写[self addTarget:self action:@selector(想函数名想半天:) forControlEvents:UIControlEventTouchUpInside ];这行代码
有需要给view添加点击事件的需求该方法也适用,需要简单改改代码
还可以给view添加个分类实现渐变色,相关文章:
(https://www.jianshu.com/p/e7c9e94e165b)
(https://www.jianshu.com/p/9f350164c766)
2.与webview交互
//再声明webView时添加代理(WKScriptMessageHandler)
[self.webView.configuration.userContentController addScriptMessageHandler:self name:@"kScriptMessageHandlerWithname"];
//实现协议方法
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
if (message.body){
if ([message.name isEqualToString:@"kScriptMessageHandlerWithname"]){
//Code...
}
}
}
//移除代理
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"kScriptMessageHandlerWithname"];
}
3.在控制台中打印中文
在iOS开发中,我们调试接口时最多的就是用NSLog 或者是打断点来po 数据,然而NSLog 输出的数据中,中文是UFT-8格式显示的,所以为了解决这个问题,今天给大家推荐一个非常好的方法,主要思路就是利用objc/runtime运行时机制 来替换掉系统的控制台输出方法,然后将utf-8格式的字符转换成中文格式。
一般情况下,我们在使用NSLog 和 %@ 输出某个对象时,就会调用这个对象的 description 方法,它的返回值就是 NSString 字符串类型,所以 description 默认实现返回的格式是 <类名: 对象的内存地址>,
在必要情况下,我们需要重写description方法以达到改变输出结果目的,覆盖description方法的默认实现。重写完description方法后,再调用NSLog(@”%@”,p)时输出结果不再是<类名: 内存地址>,而是返回的字符串。
注意:千万不要在 description 方法中同时使用 %@ 和 self,如果这样使用了,那么最终会造成程序死循环,原因是因为:如果使用了%@和self,代表要调用self的description方法,最终就是循环调用description方法。
方法:创建一个类
.h中什么都不用写
.m中如下
#import <objc/runtime.h>
static inline void zxp_swizzleSelector(Class class, SEL originalSelector, SEL swizzledSelector) {
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
if (class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))) {
class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
@implementation NSString (ZXPUnicode)
- (NSString *)stringByReplaceUnicode {
NSMutableString *convertedString = [self mutableCopy];
[convertedString replaceOccurrencesOfString:@"\\U"
withString:@"\\u"
options:0
range:NSMakeRange(0, convertedString.length)];
CFStringRef transform = CFSTR("Any-Hex/Java");
CFStringTransform((__bridge CFMutableStringRef)convertedString, NULL, transform, YES);
return convertedString;
}
@end
@implementation NSArray (ZXPUnicode)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
zxp_swizzleSelector(class, @selector(description), @selector(zxp_description));
zxp_swizzleSelector(class, @selector(descriptionWithLocale:), @selector(zxp_descriptionWithLocale:));
zxp_swizzleSelector(class, @selector(descriptionWithLocale:indent:), @selector(zxp_descriptionWithLocale:indent:));
});
}
- (NSString *)zxp_description {
return [[self zxp_description] stringByReplaceUnicode];
}
- (NSString *)zxp_descriptionWithLocale:(nullable id)locale {
return [[self zxp_descriptionWithLocale:locale] stringByReplaceUnicode];
}
- (NSString *)zxp_descriptionWithLocale:(nullable id)locale indent:(NSUInteger)level {
return [[self zxp_descriptionWithLocale:locale indent:level] stringByReplaceUnicode];
}
@end
NSDictionary、NSSet同理