美文网首页
YYKit框架学习之YYCategory -- UIView+

YYKit框架学习之YYCategory -- UIView+

作者: 番茄炒西红柿啊 | 来源:发表于2019-05-21 17:11 被阅读0次

搞开发这么久了,很少去看一些大神的代码.后悔啊.希望现在亡羊补牢,为时不晚!

这个是关于UIView的扩展

作者官方文档


属性篇:

属性名 解释
bottom frame.origin.y + frame.size.height
centerX center.x
centerY center.y
height frame.size.height
left frame.origin.x
origin frame.origin
right frame.origin.x + frame.size.width
size frame.size
top frame.origin.y
viewController 获取当前view所处的视图控制器 (下文有详解)
visibleAlpha 返回屏幕上的可见alpha,考虑superview和window (下文有详解)
width frame.size.width

其他的没什么好说的,这里说一下visibleAlphaviewController两个属性

  • viewController这个属性其实就是通过一层一层的遍历nextResponder,直到找到是UIViewController类型为止.这里涉及到"响应链"方面的知识点.
  • visibleAlpha 其实看字面解释没太弄懂意思,你可以看下作者的源码实现.源码逻辑不涉及到任何技术点,会OC语法你就能看懂.源码如下:
- (CGFloat)visibleAlpha {
    if ([self isKindOfClass:[UIWindow class]]) {
        if (self.hidden) return 0;
        return self.alpha;
    }
    if (!self.window) return 0;
    CGFloat alpha = 1;
    UIView *v = self;
    while (v) {
        if (v.hidden) {
            alpha = 0;
            break;
        }
        alpha *= v.alpha;
        v = v.superview;
    }
    return alpha;
}
  • 看完源码能够弄懂其中含义了(可视透明度,UIView 遍历到最后的根都是UIWindow
    这里用了透明度的累积), 应该是我比较菜吧,暂时不知道visibleAlpha的此段实现逻辑会在什么情况会用到.

方法篇:

方法名 类型 解释
- (CGPoint)convertPoint:(CGPoint)point toViewOrWindow:(nullable UIView *)view 实例方法 将基于调用者坐标系的point转换成基于view坐标系的point
- (CGRect)convertRect:(CGRect)rect fromViewOrWindow:(nullable UIView *)view 同上 将基于view坐标系的rect转换成相对于调用者坐标系的rect
- (CGRect)convertRect:(CGRect)rect toViewOrWindow:(nullable UIView *)view 同上 将基于调用者坐标系的rect转换成相对于view坐标系的rect
- (void)removeAllSubviews 同上 移除调用者所有的子视图
- (void)setLayerShadow:(nullable UIColor *)color offset:(CGSize)offset radius:(CGFloat)radius 同上 设置shadow, 颜色, 偏移, 圆角
- (nullable UIImage *)snapshotImage 同上 截图
- (nullable UIImage *)snapshotImageAfterScreenUpdates:(BOOL)afterUpdates 同上 截图 It’s faster than “snapshotImage”
- (nullable NSData *)snapshotPDF 同上 转换成pdf

详解

0E630441BD796968AF14DF9AF653C95A.png

如图:

  • 橙色的view,我们取名为orangeView(20, 80, 335, 200), orangeView添加在self.view上,(self是当前ViewController).
  • 黄色的view,我们取名为yellowView(10, 10, 30, 30), yellowView添加在orrangeView上.
    CGRect rect = [orangeView convertRect:CGRectMake(0, 0, 1, 1) fromViewOrWindow:self.view];
    NSLog(@"%@", NSStringFromCGRect(rect));
    // 输出为  {{-20, -80}, {1, 1}}
    
    CGPoint point = [orangeView convertPoint:CGPointMake(0, 0) fromViewOrWindow:self.view];
    NSLog(@"%@", NSStringFromCGPoint(point));
    // 输出为 {-20, -80}
    
    point = [orangeView convertPoint:CGPointMake(1, 1) toViewOrWindow:self.view];
    NSLog(@"%@", NSStringFromCGPoint(point));
    // 输出为 {21, 81}

-(void)setLayerShadow:(nullable UIColor *)color offset:(CGSize)offset radius:(CGFloat)radius

这个设置阴影没什么好说的,不过阅读源码的时候发现了2句我之前没有用过的属性

self.layer.shouldRasterize = YES;
self.layer.rasterizationScale = [UIScreen mainScreen].scale;

解释:

光栅化
《iOS 开发中的离屏渲染问题》中提到的 GPU 离屏渲染是自动触发的,而开启光栅化,是手动启动离屏渲染,并且将离屏渲染的工作交由 CPU 处理。

开启光栅化会将图层渲染为一个屏幕之外的位图(bitmap),然后将这个位图缓存起来。图层有复杂的视觉效果,这样做就会比重绘所有帧划划算的多。但是光栅化原始图像需要时间,而且还会消耗额外的内存。

当我们使用得当,光栅化可以提供很大的性能优势,但是一定要避免用在内容是动态变化的图层上,不然它缓存方面的优势就会丧失,而且会让性能变的更糟另外要注意的一点,设置 shouldRasterize 的同时也要设置 rasterizationScale。

上文解释中加粗的部分请额外注意.

额外补充:
最优设置
在《iOS 性能优化之视图圆角》中提到了几种性能优化的方法,开启光栅化也能起到一定的性能优化作用。

经过测试,对于 tableView 来说,光栅化性能最好的方式是是开启 cell 的 shouldRasterize,并将 rasterizationScale 设置为 UIScreen.main.scale。如果设置cell.layer.rasterizationScale = cell.layer.contentsScale则会出现视图模糊的现象。

cell.layer.shouldRasterize = true
cell.layer.rasterizationScale = UIScreen.main.scale
若 cell 中有多个需要离屏渲染的子视图,对每个子视图分别开启光栅化并不会优化性能,反而可能造成性能下降。

参考文献

关于截屏- (nullable UIImage *)snapshotImageAfterScreenUpdates:(BOOL)afterUpdates

afterUpdates参数为YES,代表视图的属性改变渲染完毕后截屏,参数为NO代表立刻将当前状态的视图截图

光看理论云里雾里? ok,我们直接撸代码(上方为视图view,下方为view的截图,点击开关的时候开始调用截图方法):

  • afterUpdates = NO


    图二.gif


  • afterUpdates = YES;


    图3.gif



看完上面的演示,原理一目了然.

写在最后

看到网上有部分较老的文章有提到UIView+YYAdd这个扩展和Masonry有冲突.什么self.left之类的使用失效问题.不过我看了最新的Masonry源码都加了前缀,现在都是mas_left之类.使用过程中目前我也没发现什么问题.这个问题应该是不会存在了.

相关文章

网友评论

      本文标题:YYKit框架学习之YYCategory -- UIView+

      本文链接:https://www.haomeiwen.com/subject/agnjzqtx.html