1.UITableView算高度
UITableView算高度最好不要用以下2行代码自动撑高度, iOS9.0上reloadData后,tableview会滚到顶部
rowHeight = UITableViewAutomaticDimension;
estimatedRowHeight = xxx
2.UIKeyboardWillShowNotification 通知获取键盘高度
CGRect keyboardEndFrame = [noti.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
系统自带键盘回调一次
搜狗键盘回调3次 键盘高度分别是 0 , 226, 292,如果进行动画可能发生跳动
2.FLEXBOX布局
属性定义了子视图的主轴方向 column:是上下 row:左右
flexDirection: column, row, column-reverse, row-reverse
属性定义了子视图在主轴上的对齐方式
justifyContent: flex-start | flex-end | center | space-between | space-around | space-evenly
属性定义项目在交叉轴上的对齐方式
alignItems: flex-start | flex-end | center | baseline | stretch
3.真机调试包地址
https://github.com/iGhibli/iOS-DeviceSupport/tree/master/DeviceSupport
4 TextView 相关
去除 textView 左右边距:
self.textView.textContainer.lineFragmentPadding = 0;
去除 textView 上下边距:
self.textView.textContainerInset = UIEdgeInsetsZero;
判断输入是否有高亮部分
UITextRange *selectedRange = [textView markedTextRange];
//获取高亮部分
UITextPosition *position = [textView positionFromPosition:selectedRange.start offset:0];
// 如果在变化中是高亮部分在变,就不要计算字符了
if (!(selectedRange && position)) {
// 输入完成
}
5 TextFiled 相关
自定义占位符颜色
- (void)drawPlaceholderInRect:(CGRect)rect {
// 先计算size
CGSize size = [self.placeholder sizeWithAttributes:@{NSFontAttributeName : self.font}];
[self.placeholder drawInRect:CGRectMake(0, (rect.size.height - size.height) / 2.0, rect.size.width, rect.size.height)
withAttributes:@{NSForegroundColorAttributeName : self.placeholderColor, NSFontAttributeName : self.font}];
}
6、 Delegate和Notification有什么区别
说一对一和一对多的区别就很low了
Delegate模式也是能够实现出一对多的功能的(例如XMPP的Multi Delegate)。
他们之间的本质区别就在于命令式和响应式。
假设你现在是主人,你肚子饿了。你需要让你的仆人们给你做饭,端过来给你吃。
- 命令式
1. 对仆人中负责买菜的人吩咐你去买菜带给你
2. 你拿着仆人买来的菜,给到负责做菜的仆人,吩咐他去做菜
3. 厨师做好菜端给你,你就可以吃了
- 响应式
你喊一声:我肚子饿了!
1. 负责买菜的仆人听到你喊的这一声,就去买菜了,买好菜就放到仓库里,然后喊一声:"我买好菜了!"
2. 负责做菜的仆人听到买菜的仆人喊的这一声,就去仓库里拿东西做菜,做好了端给你。
7、 NSMutableParagraphStyle
- 系统会复用这个对象, 2个段富文本都new了NSMutableParagraphStyle,但是打印出来的 地址是一个, 这时候 如果我们改变这个对象的一些属性, 2段文本会同时改变, 这是 系统的一个优化需要注意
- (void)paragraphStyle {
NSMutableParagraphStyle *style1 = [[NSMutableParagraphStyle alloc]init];
style1.tailIndent = 10;
NSMutableAttributedString *atrr1 = [[NSMutableAttributedString alloc]initWithString:@"此外,新增动态计算功能,轻松支持同比、环比及加减乘除等运算需求!" attributes:@{NSParagraphStyleAttributeName: style1}];
NSMutableParagraphStyle *style2 = [[NSMutableParagraphStyle alloc]init];
style2.tailIndent = 10;
NSMutableAttributedString *atrr2 = [[NSMutableAttributedString alloc]initWithString:@"曼城意外折戟,热刺强势晋级!北京时间10月31日凌晨,英格兰联赛杯第4轮的较量上演了一场引人瞩目的对决。" attributes:@{NSParagraphStyleAttributeName: style2}];
[self check_paragraphStyle:atrr1];
[self check_paragraphStyle:atrr2];
}
- (void)check_paragraphStyle:(NSAttributedString *)attributedText {
NSLog(@"");
[attributedText enumerateAttribute:NSParagraphStyleAttributeName inRange:NSMakeRange(0, attributedText.length) options:0 usingBlock:^(NSParagraphStyle *value, NSRange range, BOOL * _Nonnull stop) {
NSLog(@"%@", value);
}];
}
8、有用的文章
缓存 https://zhuanlan.zhihu.com/p/591436083
网络 https://zhuanlan.zhihu.com/p/405387352
虚拟定位 https://zhuanlan.zhihu.com/p/451765172
防定位黑产 https://www.jianshu.com/p/84830b9ebde0
SwiftHook(libffi库) https://blog.csdn.net/gitblog_00080/article/details/139516503
内存 https://wetest.qq.com/labs/367
9、RunLoop 和 GCD
NSLog(@"开始")
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"执行")
});
NSLog(@"结束")
打印顺序: 开始 -> 结束 -> 执行
- 上面代码gcd的block会在新的一轮runloop中执行, 他的执行时机是什么呢?
GCD 在调用dispatch_async之后不会立刻执行block而是把block存起来, 猜测其内部监听了 runloop的kCFRunLoopBeforeWaiting状态
这时候通过Dispatch port 注册的Source1唤醒runloop
执行这个方法
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__(msg);
这个方法内部是和GCD进行通信, 去执行存在主队列里面的block
10、dispatch_after
使用dispatch_after还有一个问题就是取消问题,当然通常遇到了这种问题大部分答案就是使用下面的方式:
[self performSelector:@selector(myDelayedMethod) withObject: self afterDelay: desiredDelay];
[NSObject cancelPreviousPerformRequestsWithTarget: self selector:@selector(myDelayedMethod) object: self];
不过如果你使用的是iOS 8及其以上的版本,那么其实是可以取消的(如下),当然如果你还在支持iOS 8以下的版本不妨试试这个自定义的dispatch_cancelable_block_t类:
dispatch_block_t block = dispatch_block_create(DISPATCH_BLOCK_INHERIT_QOS_CLASS, ^{
NSLog(@"dispatch_after...");
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3*NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), block);
// 取消
dispatch_block_cancel(block);
11. UICollectionView
- minimumInteritemSpacing 和 minimumInteritemSpacing 设置为同一个值时
- 并且 UICollectionView是由多组构成
UICollectionView 在滑动中 一些item会隐藏不见