集聚不符合这一次的题目研商卡塔尔,都不汇合世图层混合

那二日做的类型主借使LBS那块 主打成员定位功效 我们的UI设计是如此的

图片 1

图片 2

core animation.png

乍一看上去是蛮好挺美貌的 分歧的人会来得区别的头像 然而当人扎堆的时候 难题就来了

1.Core Animation使用

图片 3

  • 图层混合 Color Blended Layers
    UIView的opaque属性暗中认可值正是true,约等于说只要不是人造设置成透明,都不会产出图层混合
    对此UIImageView来讲,不止它自己需若是不透明的,它的图样也不可能含有阿尔法通道
    个体感觉比opaque属性更首要的是backgroundColor属性,假使不安装那本性情,控件照旧被以为是透明的
    而是当UILabel内容为华语时,label的实际渲染区域要大于label的size,因为外面有了一圈的阴影,才会现出图层混合我们需求给粤语的label加上如下代码:

      retweededTextLab?.layer.masksToBounds = true
      retweededTextLab?.backgroundColor = UIColor.groupTableViewBackground
      statusLab.layer.masksToBounds = true
      statusLab.backgroundColor = UIColor.white
    
  • Color Hits Green and Misses Red 光栅化
    光栅化是将八个layer预先渲染成位图(bitmap卡塔尔国,然后参加缓存中
    “Color Hits Green and Misses Red”,它表示只要命中缓存则呈现为土灰,不然呈现为革命,鲜明纯白更加的多越好,茶绿越少越好

  • 图片格式转化 Color Copied Images
    CPU首要管理两件事:
    把图片从PNG或JPEG等格式中解压出来,获得像素数量
    如果GPU不协助这种颜色各类,CPU供给开展格式调换,比方采纳中有一点点从网络下载的图片,“Color Copied Images”就用来检查实验这种实时的格式转变,假如有则会将图片标识为影青

  • 图表缩放 Color Misaligned Images
    它意味着只要图片要求缩放则标志为香艳,若无像素对齐则标识为栗褐
    图片的缩放须求占用时间,由此我们要硬着头皮保障不管地方图片如故从互联网或获得图片的大大小小,都与其frame保持一致。

  • 离屏渲染 Color Offscreen-Rendered Yellow
    以下处境恐怕会引致触发离屏渲染:
    1.重写drawRect方法
    2.有mask只怕是影子(layer.masksToBounds, layer.shadow*卡塔尔,模糊效果也是一种mask
    3.layer.shouldRasterize = true
    消除方案是硬着头皮在滑行时防止设置圆角,假设必得安装圆角,能够应用光栅化技艺将圆角缓存起来

  • 改造区域 Flash updated Regions
    刷新视图时,大家应当把需求重绘的区域尽量压缩。对于未爆发变化的内容则不应该重绘
    施工方案

当人多的时候(举例上图所示State of Qatar 地图滑动起来就会感觉到明显顿卡 这种不流畅感能折磨死人 所以 自然我们要消除那个难题(等等 先不要戏弄怎么不要地图聚合 因为这一度是地图放到最大了 聚合不合乎本次的难点商讨卡塔尔(قطر‎

分析

首先看下作者是怎么贯彻那几个annotationView的 由于这几个annotationsView是异形的(也正是爱莫能助透过设置圆角直接拿走卡塔尔(قطر‎並且内部的图形还因顾客而异 所以解决方案正是行使layer.mask来进展遮罩 代码如下:

@implementation MMAnnotationView

- (instancetype)initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
    if ( self )
    {
        self.frame = CGRectMake(0, 0, TRACK_ANNOTATION_SIZE.width, TRACK_ANNOTATION_SIZE.height);
        self.centerOffset = CGPointMake(0, -(TRACK_ANNOTATION_SIZE.height-3)/2);
        self.canShowCallout = NO;

        self.avatarView = [[UIImageView alloc] initWithFrame:self.bounds];
        [self addSubview:self.avatarView];
        self.avatarView.contentMode = UIViewContentModeScaleAspectFill;

        CAShapeLayer *shapelayer = [CAShapeLayer layer];
        shapelayer.frame = self.bounds;
        shapelayer.path = self.framePath.CGPath;
        self.avatarView.layer.mask = shapelayer;

        self.layer.shadowPath = self.framePath.CGPath;
        self.layer.shadowRadius = 1.0f;
        self.layer.shadowColor = [UIColor colorWithHex:0x666666FF].CGColor;
        self.layer.shadowOpacity = 1.0f;
        self.layer.shadowOffset = CGSizeMake(0, 0);
        self.layer.masksToBounds = NO;
    }
    return self;
}

//mask路径
- (UIBezierPath *)framePath
{
    if ( !_framePath )
    {
        CGFloat arrowWidth = 14;

        CGMutablePathRef path = CGPathCreateMutable();

        CGRect rectangle = CGRectInset(CGRectMake(0, 0, CGRectGetWidth(self.bounds), CGRectGetWidth(self.bounds)), 3,3);

        CGPoint p[3] = {
        {CGRectGetMidX(self.bounds)-arrowWidth/2, CGRectGetWidth(self.bounds)-6},
        {CGRectGetMidX(self.bounds)+arrowWidth/2, CGRectGetWidth(self.bounds)-6},
        {CGRectGetMidX(self.bounds), CGRectGetHeight(self.bounds)-4}
        };

        CGPathAddRoundedRect(path, NULL, rectangle, 5, 5);
        CGPathAddLines(path, NULL, p, 3);

        CGPathCloseSubpath(path);

        _framePath = [UIBezierPath bezierPathWithCGPath:path];

        CGPathRelease(path);
    }

    return _framePath;
}

自个儿用代码生成了样子路线 并以此生成了layer的mask和shadowPath,使用时 只要直接用SDWebImage设置头像就能够了

[annotationView.avatarView sd_setImageWithURL:[NSURL URLWithString:avatarURL] placeholderImage:placeHolderImage];

接下去用工具深入分析一下标题出来哪 深入分析质量当然是筛选Instrments(用法在此就不做牵线了卡塔尔 张开Core Animation 然后运路程序 滑动地图 能够看出质量剖析如下

图片 4

原来平均帧数唯有不到30帧 那离大家的靶子60帧差得实在太远

再选拔Debug Option来深入解析一下

图片 5

出于MKMapView的开始和结果 这里大家主要关怀那多少个接受

  • Color Blended Layers
  • Color Misaligned Images
  • Color Offscreen-Rendered Yellow

分级张开这多少个筛选 结果如下

图片 6

能够见见

  • Color Blended Layers未曾难点 不过这也是寻常的 由于使用了mask 未有透明的地点
  • Color Misaligned Images除了暗中认可头像外全中 那是因为服务器上的图片大小跟显示的朗朗上口不均等 引致缩放 而暗许头像则是平等的 所以没难题
  • Color Offscreen-Rendered Yellow全中 由于接纳了mask 导致大量的离屏渲染 这也是性质收缩的主要性缘由

解决

题指标来由找到了 那么接下去该怎样缓慢解决吗?

  • 首先mask是必定不能够用了
  • 说不上下载下来的图纸我们要预管理成实际上尺寸

那即是说 直接把下载下来的图形合成为大家要展示的最后结出不就ok了呢? 试试看

- (void)loadAnnotationImageWithURL:(NSString*)url imageView:(UIImageView*)imageView
{
    //将合成后的图片缓存起来
    NSString *annoImageURL = url;
    NSString *annoImageCacheURL = [annoImageURL stringByAppendingString:@"cache"];

    UIImage *cacheImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:annoImageCacheURL];
    if ( cacheImage )
    {
        //LLLog(@"hit cache");
        imageView.image = cacheImage;
    }
    else
    {
        //LLLog(@"no cache");
        [imageView sd_setImageWithURL:[NSURL URLWithString:annoImageURL]
        placeholderImage:placeHolderImage
        completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
        if (!error)
        {
            UIImage *annoImage = [image annotationImage];
            imageView.image = annoImage;

            [[SDImageCache sharedImageCache] storeImage:annoImage forKey:annoImageCacheURL];
            }
        }];
    }
}

@implementation UIImage (LJC)
- (UIImage*) annotationImage
{
    static UIView *snapshotView = nil;
    static UIImageView *imageView = nil;

    if ( !snapshotView )
    {
        snapshotView = [UIView new];
        snapshotView.frame = CGRectMake(0, 0, TRACK_ANNOTATION_SIZE.width, TRACK_ANNOTATION_SIZE.height);

        imageView = [UIImageView new];
        [snapshotView addSubview:imageView];
        imageView.clipsToBounds = YES;
        imageView.frame = snapshotView.bounds;
        imageView.contentMode = UIViewContentModeScaleAspectFill;

        CGFloat arrowWidth = 14;

        CGMutablePathRef path = CGPathCreateMutable();

        CGRect rectangle = CGRectInset(CGRectMake(0, 0, CGRectGetWidth(imageView.bounds), CGRectGetWidth(imageView.bounds)), 3,3);

        CGPoint p[3] = {
            {CGRectGetMidX(imageView.bounds)-arrowWidth/2, CGRectGetWidth(imageView.bounds)-6},
            {CGRectGetMidX(imageView.bounds)+arrowWidth/2, CGRectGetWidth(imageView.bounds)-6},
            {CGRectGetMidX(imageView.bounds), CGRectGetHeight(imageView.bounds)-4}
        };

        CGPathAddRoundedRect(path, NULL, rectangle, 5, 5);
        CGPathAddLines(path, NULL, p, 3);

        CGPathCloseSubpath(path);

        CAShapeLayer *shapelayer = [CAShapeLayer layer];
        shapelayer.frame = imageView.bounds;
        shapelayer.path = path;

        imageView.layer.mask = shapelayer;

        snapshotView.layer.shadowPath = path;
        snapshotView.layer.shadowRadius = 1.0f;
        snapshotView.layer.shadowColor = [UIColor colorWithHex:0x666666FF].CGColor;
        snapshotView.layer.shadowOpacity = 1.0f;
        snapshotView.layer.shadowOffset = CGSizeMake(0, 0);

        CGPathRelease(path);
    }

    imageView.image = self;

    UIGraphicsBeginImageContextWithOptions(TRACK_ANNOTATION_SIZE, NO, 0);

    [snapshotView.layer renderInContext:UIGraphicsGetCurrentContext()];

    UIImage *copied = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return copied;
}
@end

然后使用的时候 只要轻松的如下调用就OK了

[self loadAnnotationImageWithURL:avatarURL imageView:annotationView.avatarView];

会见改正以往的Instruments表现怎么样

图片 7

  • Color Blended Layers全中 那也是无可防止的 因为展示的正是一张带发光度的图 然而出于地图的特殊性(头像的职分变动间距较长 所以不会平常引发合成 也未曾动漫卡塔尔 所以这里亦非主题材料
  • Color Misaligned Images没难题了 因为头像已被缩放成了相似大小
  • Color Offscreen-Rendered Yellow没难点了 因为只是轻松的来得了一张图纸 而并不曾索要离屏渲染的事物了

再来看下帧数情状

图片 8

Oh-Yeah~ 不光帧数达到了笔者们的靶子60帧(由于还会有工作逻辑线程在后台跑 所以没有那么的水静无波卡塔尔国 就连平均运营耗费时间都下降了繁多即便地图上再多呈现几拾一个人 也小难题了

小结

不唯有是MKMapView 其实满含UITableView在内的不菲地点都能够用文中所说的不二等秘书诀去优化 其宗旨点正是 合成+缓存 当然 由于合成仍旧会开支一部分能源的 所以比较切合头像这种小的财富

有关图形质量优化 能够看下这篇好文(有对文中提到的Debug Option不太掌握的 这里有详尽的表明卡塔尔国

本文由美高梅4688官方网站发布于最新话题,转载请注明出处:集聚不符合这一次的题目研商卡塔尔,都不汇合世图层混合

您可能还会对下面的文章感兴趣: