美文网首页
iOS9之后圆角与阴影性能优化

iOS9之后圆角与阴影性能优化

作者: _码奴 | 来源:发表于2019-01-10 15:09 被阅读0次

    圆角和阴影实现代码和各种实现方法对比都在下面,并且做了注释,可以查看注释了解差异和优劣

    #import "ViewExtendController.h"
    #import "UIImageView+DrawEx.h"
    
    @interface ViewExtendController ()<UITableViewDelegate,UITableViewDataSource>
    
    @property (nonatomic,strong) UIImageView * imageView;
    @property (nonatomic,strong) UIButton * button;
    
    @property (nonatomic,strong) UITableView * tableView;
    
    @end
    
    @implementation ViewExtendController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.title = @"View扩展功能";
        [self makeView];
    }
    
    - (void)makeView {
        self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 64, 100, 100)];
        [self.view addSubview:self.imageView];
        self.imageView.backgroundColor = [UIColor redColor];
        self.imageView.layer.cornerRadius = 50;
    //    self.imageView.layer.masksToBounds = YES;
        
        self.imageView.layer.shadowColor = UIColor.greenColor.CGColor;
        self.imageView.layer.shadowOffset = CGSizeMake(3, 5);
        self.imageView.layer.shadowRadius = 10;
        self.imageView.layer.shadowOpacity = 0.7;
        // 上面阴影代码会离屏渲染,加上下面这句不会离屏渲染
        // 创建一个圆形贝塞尔曲线, 加上这句,视图不进行离屏渲染
    /*
         * 这个方法会检测出内存泄漏 CGPathCreateWithRoundedRect
         * 但是实际应该没有影响,因为如果释放程序会立刻崩溃,感觉应该只是系统延迟释放了,所以才会检测出泄漏
         */
    //UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:im.bounds byRoundingCorners:UIRectCornerAllCorners cornerRadii:im.bounds.size];
    //    self.imageView.layer.shadowPath = path.CGPath;
    // 这个方法会检测出内存泄漏,CGPathCreateWithRoundedRect(self.imageView.bounds, self.imageView.bounds.size.width, self.imageView.bounds.size.height, NULL);  所以保险起见这里改成上面的方式
        
        [self.view addSubview:self.tableView];
        
    }
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return 50;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        ViewExtendCell * cell = [tableView dequeueReusableCellWithIdentifier:@"ViewExtendCell" forIndexPath:indexPath];
        for(UIImageView * im in cell.viewsArray) {
            // masksToBounds iOS9 之后不会离屏渲染,对帧率影响不明显
    //        im.layer.cornerRadius = im.bounds.size.width/2;
    //        im.layer.masksToBounds = YES; // 这句,不离屏,但是还是会有额外渲染,因为毕竟要裁剪圆角,主要问题是不能显示阴影,因为阴影也会被裁减掉
            
            im.image = [UIImage imageNamed:@"timg"];
            // 这个方法可以对帧率影响不明显,并且能在实现圆角的情况下不影响阴影的显示
            [im drawCornerRadius:im.frame.size.width/2]; //这个方法来自是定义的类别中,下面有给出代码
            
        }
        return cell;
    }
    
    - (UITableView *)tableView {
        if(!_tableView) {
            self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 164, self.view.frame.size.width, self.view.frame.size.height - 164) style:UITableViewStylePlain];
            self.tableView.delegate = self;
            self.tableView.dataSource = self;
            self.tableView.rowHeight = 60;
            [self.tableView registerClass:[ViewExtendCell class] forCellReuseIdentifier:@"ViewExtendCell"];
        }
        return _tableView;
    }
    
    @end
    
    
    @implementation ViewExtendCell
    
    - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
        self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
        if(self) {
            [self makeCell];
        }
        return self;
    }
    
    - (void)makeCell {
        
        NSMutableArray * viewArray = [[NSMutableArray alloc] init];
        
        self.iconImage = [[UIImageView alloc] initWithFrame:CGRectMake(20, 5, 50, 50)];
        [self.contentView addSubview:self.iconImage];
        
        
        self.iconImage_1 = [[UIImageView alloc] initWithFrame:CGRectMake(75, 5, 50, 50)];
        [self.contentView addSubview:self.iconImage_1];
        
        self.iconImage_2 = [[UIImageView alloc] initWithFrame:CGRectMake(130, 5, 50, 50)];
        [self.contentView addSubview:self.iconImage_2];
        
        self.iconImage_3 = [[UIImageView alloc] initWithFrame:CGRectMake(185, 5, 50, 50)];
        [self.contentView addSubview:self.iconImage_3];
    //    self.iconImage_3.layer.cornerRadius = 10;
    //    self.iconImage_3.layer.masksToBounds = YES;
        
        self.iconImage_4 = [[UIImageView alloc] initWithFrame:CGRectMake(240, 5, 50, 50)];
        [self.contentView addSubview:self.iconImage_4];
    //    self.iconImage_4.layer.cornerRadius = 10;
    //    self.iconImage_4.layer.masksToBounds = YES;
        
        self.iconImage.image = [UIImage imageNamed:@"timg"];
        self.iconImage_1.image = [UIImage imageNamed:@"timg"];
        self.iconImage_2.image = [UIImage imageNamed:@"timg"];
        self.iconImage_3.image = [UIImage imageNamed:@"timg"];
        self.iconImage_4.image = [UIImage imageNamed:@"timg"];
        
        [viewArray addObject:self.iconImage];
        [viewArray addObject:self.iconImage_1];
        [viewArray addObject:self.iconImage_2];
        [viewArray addObject:self.iconImage_3];
        [viewArray addObject:self.iconImage_4];
        for(UIImageView * im in viewArray) {
            // masksToBounds iOS9 之后不会离屏渲染,对帧率影响不明显
    //        im.layer.cornerRadius = im.bounds.size.width/2;
    //        im.layer.masksToBounds = YES; // 这句,不离屏,但是还是会有额外渲染,因为毕竟要裁剪圆角,主要问题在于会影响阴影的显示
            
            // iOS9之后还是会造成离屏渲染了,下面使用 layer.mask 会离屏渲染,并且太多会影响帧率
    //        UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:im.bounds byRoundingCorners:UIRectCornerAllCorners cornerRadii:im.bounds.size];
    //        CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init];
    //        //设置大小
    //        maskLayer.frame = im.bounds;
    //        //设置图形样子
    //        maskLayer.path = maskPath.CGPath;
    //        im.layer.mask = maskLayer;  // iOS9之后还是会造成离屏渲染了,
            
            // 因为上面有圆形测试代码m,设置了masksToBounds,所以下面阴影其实看不到
            // 直接使用这种阴影会离屏渲染,但是帧率影响不明显,
            im.layer.shadowColor = UIColor.greenColor.CGColor;
            im.layer.shadowOffset = CGSizeMake(3, 5);
            im.layer.shadowRadius = 10;
            im.layer.shadowOpacity = 0.7;
            //上面代码,阴影离屏渲染不太影响帧率,但是会对GUP消耗很大,这可能是阴影过多卡顿的主要原因
            // 创建一个圆形贝塞尔曲线, 加上这句,阴影不再进行离屏渲染,并且降低GPU的资源占用率
            UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:im.bounds byRoundingCorners:UIRectCornerAllCorners cornerRadii:im.bounds.size];
            im.layer.shadowPath = path.CGPath;
            //这个方法会内存泄漏,使用上面方法 CGPathCreateWithRoundedRect(im.bounds, im.bounds.size.width, im.bounds.size.height, NULL);,但实际应该没有影响,只是被延迟释放了而已,为了保险还是使用上面方法
            
        }
        
        self.viewsArray = viewArray;
        
    }
    
    @end
    

    下面是 "UIImageView+DrawEx.h" 类的代码,这个里面没写什么,依托于UIImage+Corner.h这个类

    #import "UIImageView+DrawEx.h"
    #import "UIImage+Corner.h"
    
    @implementation UIImageView (DrawEx)
    
    - (UIImage *)drawCornerRadius:(CGFloat)cornerRadius {
        // 获取裁减成圆角的图片,并重新赋值给imageview的image
        UIImage * image = [self.image drawCornerInRect:self.bounds cornerRadius:cornerRadius];
        self.image = image;
        return image;
    }
    
    @end
    

    下面是 UIImage+Corner类代码实现,

    #import "UIImage+Corner.h"
    
    @implementation UIImage (Corner)
    
    
    - (UIImage *)drawCornerInRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius {
        UIImage * image = nil;
        // 创建贝塞尔曲线对象
        UIBezierPath * bezierPath = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:cornerRadius];
        // 开始设置绘图
        UIGraphicsBeginImageContextWithOptions(rect.size, false, [UIScreen mainScreen].scale);
        CGContextAddPath(UIGraphicsGetCurrentContext(), bezierPath.CGPath);
        CGContextClip(UIGraphicsGetCurrentContext());
        // 调用绘制方法
        [self drawInRect:rect];
        
        // 绘制图片
        CGContextDrawPath(UIGraphicsGetCurrentContext(), kCGPathFillStroke);
        // 获取绘制完成的image
        image = UIGraphicsGetImageFromCurrentImageContext();
        // 结束绘制
        UIGraphicsEndImageContext();
        
        return image;
    }
    
    @end
    

    相关文章

      网友评论

          本文标题:iOS9之后圆角与阴影性能优化

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