How to clear font cache filled with emoji characters?

前端 未结 6 416
日久生厌
日久生厌 2020-12-13 19:52

I am developing keyboard extension for iPhone. There is an emoji screen smilar to Apples own emoji keyboard that shows some 800 emoji characters in UICollectionView

6条回答
  •  不思量自难忘°
    2020-12-13 20:21

    In my case, the plain CATextLayer helped to reduce the memory usage of my app. When I used the UILabel to render Emojis the keyboard extension memory was increasing from ~16MB to ~76MB. After the replacement of the UILabel with the CATextLayer, the keyboard extension memory increasing from ~16MB to only ~26MB.

    Previous UICollectionViewCell subclass setup:

    - (instancetype)initWithFrame:(CGRect)frame {
        self = [super initWithFrame:frame];
    
        // somewhere in the header file 
        // @property (nonatomic, strong, readonly) UILabel *textLabel;
        _textLabel = [UILabel new];
        self.textLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:28];
        self.textLabel.textAlignment = NSTextAlignmentCenter;
        [self addSubview:self.textLabel];
        // some auto layout logic using Masonry
        [self.textLabel mas_makeConstraints:^(MASConstraintMaker *make) {
            make.size.equalTo(self);
            make.center.equalTo(self);
        }];
    
        return self;
    }
    

    My UICollectionViewCell subclass setup with the CATextLayer:

    - (instancetype)initWithFrame:(CGRect)frame {
        self = [super initWithFrame:frame];
    
        // somewhere in the header file 
        // @property (nonatomic, strong, readonly) CATextLayer *textLayer;
        _textLayer = [CATextLayer new];
        self.textLayer.frame = CGRectMake(0, 0, 33, 33);
        self.textLayer.font = CFBridgingRetain([UIFont fontWithName:@"HelveticaNeue" size:28].fontName);
        self.textLayer.fontSize = 28;
        self.textLayer.alignmentMode = kCAAlignmentCenter;
        [self.layer addSublayer:self.textLayer];
    
        return self;
    }
    

    Update

    Sorry guys forgot to add the self.textLayer.contentsScale = [[UIScreen mainScreen] scale]; to get clear text. That unfortunately increased usage of memory from ~16MB to ~44MB, but still better than the UILabel solution.

    Final UICollectionViewCell subclass setup with the CATextLayer:

    - (instancetype)initWithFrame:(CGRect)frame {
        self = [super initWithFrame:frame];
    
        [self.layer setRasterizationScale:[[UIScreen mainScreen] scale]];
    
        // somewhere in the header file 
        // @property (nonatomic, strong, readonly) CATextLayer *textLayer;
        _textLayer = [CATextLayer new];
        self.textLayer.frame = CGRectMake(0, 0, 33, 33);
        self.textLayer.font = CFBridgingRetain([UIFont fontWithName:@"HelveticaNeue" size:28].fontName);
        self.textLayer.fontSize = 28;
        self.textLayer.alignmentMode = kCAAlignmentCenter;
        NSDictionary *newActions = @{
            @"onOrderIn": [NSNull null],
            @"onOrderOut": [NSNull null],
            @"sublayers": [NSNull null],
            @"contents": [NSNull null],
            @"bounds": [NSNull null]
        };
        self.textLayer.actions = newActions;
        [self.layer addSublayer:self.textLayer];
    
        [self.layer setShouldRasterize:YES];
    
        return self;
    }
    

提交回复
热议问题