UIView实现逐行加载的效果

最近在项目中要实现一个逐行加载的效果

具体实现步骤

1.需要把UIView转换成UIImage对象

2.运用CALayer对image进行逐行显示

假设当前的view为:

1
2
UIView *loadView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
loadView.backgroundColor = [UIColor redColor];

实现第一步:

把UIview转换成UIImage
1
2
3
4
5
6
7
8
9
10
11
- (UIImage *)convertViewToImage:(UIView *)view {
CGSize size = view.bounds.size;
CGFloat scale = [UIScreen mainScreen].scale; // 用来适配当前的设备屏幕是否Retina,不然截屏会变得模糊
UIGraphicsBeginImageContextWithOptions(size, NO, scale);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, 0, 0);
[view.layer renderInContext:context];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}

实现第二步:

运用CALayer对image进行逐行显示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
UIImage *image = [self convertViewToImage:loadView];

_nowHeight = 0; //标记当前显示loadView的高度, PS:_nowHeight为全局变量
CALayer *layer = [CALayer layer];
layer.frame = (CGRect){.origin=CGPointZero, .size=CGSizeMake(loadView.frame.size.width, 0)};
layer.contents = (id)image.CGImage;
layer.contentsScale = [UIScreen mainScreen].scale;
layer.masksToBounds = YES;
layer.contentsGravity = kCAGravityBottom;
[CATranscation flush];
[loadView.layer addSublayer:layer];
_layer = layer; //PS:_layer为全局变量

_timer = [NSTimer scheduledTimerWithTimeInterval:.5 target:self selector:@selector(updateLoadViewHeight:) userInfo:@{@"view":loadView} repeats:YES];// PS:_timer为全局变量
执行NSTimer的回调
1
2
3
4
5
6
7
8
9
10
11
12
13
- (void)updateLadViewHeight:(NSTimer *)timer {
NSDictionary *dict = [timer userInfo];
UIView *loadView = [dict objectForKey@"view"];

_nowHeight += 2;
_layer.frame = (CGRect){.origin=CGPointZero, .size=CGSizeMake(loadView.frame.size.width, _nowHeight)};

if (_layer.frame.size.height >= height) {
_nowHeight = 0;
[_layer removeFromSuperlayer];
[timer invalidate];
}
}
文章目录
,