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); }