CALayer 有一个属性叫做contents,这个属性的类型被定义为id,意味着它可以是任何类型的对象。在这种情况下,你可以给contents属性赋任何值,你的app仍然能够编译通过。但是,在实践中,如果你给contents赋的不是CGImage,那么你得到的图层将是空白的。
CALayer的contentsRect属性允许我们在图层边框里显示寄宿图的一个子域。contentsRect不是按点来计算的,它使用了单位坐标,单位坐标指定在0到1之间,是一个相对值(像素和点就是绝对值)。所以他们是相对与寄宿图的尺寸的。默认的contentsRect是{0, 0, 1, 1},这意味着整个寄宿图默认都是可见的,如果我们指定一个小一点的矩形,图片就会被裁剪。
需求
用图上的数字来展示一个时钟。原理就是利用contentsRect来展示不同区域的数字。
关键代码
-
创建时、分、秒视图
// 展示内容contents
UIImage *image = [UIImage imageNamed:@"again"];digitViews = [NSMutableArray array]; CGFloat wide = 50; CGFloat space = 10; CGFloat x = (kScreenWidth - 50*6 - 10*5 - 20)/2; for (int i = 0; i < 6; i++) { UIView *view = [[UIView alloc] initWithFrame:CGRectMake(x+(wide+space)*i, MaxY(backView)+20, wide, 80)]; [self.view addSubview:view]; // =========== 重点 view.layer.contents = (__bridge id)image.CGImage; view.layer.contentsRect = CGRectMake(0, 0, 0.1, 1.0); view.layer.contentsGravity = kCAGravityResizeAspect; view.layer.magnificationFilter = kCAFilterNearest; // =========== [digitViews addObject:view]; }
-
计算数字
- (void)tick
{
NSDateComponents *components = [[NSCalendar currentCalendar] components:(NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond) fromDate:[NSDate date]];
// set hours
[self setDigit:components.hour / 10 forView:digitViews[0]];
[self setDigit:components.hour % 10 forView:digitViews[1]];// set minutes [self setDigit:components.minute / 10 forView:digitViews[2]]; [self setDigit:components.minute % 10 forView:digitViews[3]]; // set seconds [self setDigit:components.second / 10 forView:digitViews[4]]; [self setDigit:components.second % 10 forView:digitViews[5]]; } - (void)setDigit:(NSInteger)digit forView:(UIView *)view { NSInteger row = digit / 5; NSInteger line = digit % 5; view.layer.contentsRect = CGRectMake(line * 0.2, row * 0.53, 0.2, 0.5); }