iOS技术小Tips

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);
    }];
}
  • 修复
[attributedText enumerateAttribute:NSParagraphStyleAttributeName inRange:NSMakeRange(0, attributedText.length) options:0 usingBlock:^(NSParagraphStyle *value, NSRange range, BOOL * _Nonnull stop) {
        这里修改 value 时必须调用 value.mutableCopy
        yytext 里面的宏定义有点问题
    }];

#define ParagraphStyleSet(_attr_) \
[self enumerateAttribute:NSParagraphStyleAttributeName \
                 inRange:range \
                 options:kNilOptions \
              usingBlock: ^(NSParagraphStyle *value, NSRange subRange, BOOL *stop) { \
                  NSMutableParagraphStyle *style = nil; \
                  if (value) { \
                      if (CFGetTypeID((__bridge CFTypeRef)(value)) == CTParagraphStyleGetTypeID()) { \
                          value = [NSParagraphStyle yy_styleWithCTStyle:(__bridge CTParagraphStyleRef)(value)]; \
                      } \
                      if (value. _attr_ == _attr_) return; \
                      if ([value isKindOfClass:[NSMutableParagraphStyle class]]) { \
                          style = (id)value; \
                      } else { \
                          style = value.mutableCopy; \
                      } \
                  } else { \
                      if ([NSParagraphStyle defaultParagraphStyle]. _attr_ == _attr_) return; \
                      style = [NSParagraphStyle defaultParagraphStyle].mutableCopy; \
                  } \
                  style. _attr_ = _attr_; \
                  [self yy_setParagraphStyle:style range:subRange]; \
              }];

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);

GCD源码解读
RunLoop

11. UICollectionView

  • minimumInteritemSpacing 和 minimumInteritemSpacing 设置为同一个值时
  • 并且 UICollectionView是由多组构成
    UICollectionView 在滑动中 一些item会隐藏不见
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容