图片赛过千言万语,界面抵得上千图片 ——Ben Shneiderman git
咱们在第一章『图层树』中介绍了CALayer类并建立了一个简单的有蓝色背景的图层。背景颜色还好啦,可是若是它仅仅是展示了一个单调的颜色未免也太无聊了。事实上CALayer类可以包含一张你喜欢的图片,这一章节咱们未来探索CALayer的寄宿图(即图层中包含的图)。 github
CALayer 有一个属性叫作contents,这个属性的类型被定义为id,意味着它能够是任何类型的对象。在这种状况下,你能够给contents属性赋任何值,你的app仍然可以编译经过。可是,在实践中,若是你给contents赋的不是CGImage,那么你获得的图层将是空白的。 app
contents这个奇怪的表现是由Mac OS的历史缘由形成的。它之因此被定义为id类型,是由于在Mac OS系统上,这个属性对CGImage和NSImage类型的值都起做用。若是你试图在iOS平台上将UIImage的值赋给它,只能获得一个空白的图层。一些初识Core Animation的iOS开发者可能会对这个感到困惑。 ide
头疼的不单单是咱们刚才提到的这个问题。事实上,你真正要赋值的类型应该是CGImageRef,它是一个指向CGImage结构的指针。UIImage有一个CGImage属性,它返回一个"CGImageRef",若是你想把这个值直接赋值给CALayer的contents,那你将会获得一个编译错误。由于CGImageRef并非一个真正的Cocoa对象,而是一个Core Foundation类型。 函数
尽管Core Foundation类型跟Cocoa对象在运行时貌似很像(被称做toll-free bridging),他们并非类型兼容的,不过你能够经过bridged关键字转换。若是要给图层的寄宿图赋值,你能够按照如下这个方法: spa
1
2
|
//设置图层的内容显示为一张图片
layer.contents = (__bridge id)image.CGImage;
|
若是你没有使用ARC(自动引用计数),你就不须要__bridge这部分。可是,你干吗不用ARC?! .net
让咱们来继续修改咱们在第一章新建的工程,以便可以展现一张图片而不单单是一个背景色。咱们已经用代码的方式创建一个图层,那咱们就不须要额外的图层了。那么咱们就直接把layerView的宿主图层的contents属性设置成图片。 指针
清单2.1 更新后的代码。 对象
1
2
3
4
5
6
7
8
9
10
11
|
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad]; <br> //load an image
UIImage *image = [UIImage imageNamed:@"Snowman.png"];
//add it directly to our view's layer
self.layerView.layer.contents = (__bridge id)image.CGImage;
}
|
图表2.1 在UIView的宿主图层中显示一张图片 图片
咱们用这些简单的代码作了一件颇有趣的事情:咱们利用CALayer在一个普通的UIView中显示了一张图片。这不是一个UIImageView,它不是咱们一般用来展现图片的方法。经过直接操做图层,咱们使用了一些新的函数,使得UIView更加有趣了。
contentGravity
你可能已经注意到了咱们的雪人看起来有点。。。胖 ==! 咱们加载的图片并不恰好是一个方的,为了适应这个视图,它有一点点被拉伸了。在使用UIImageView的时候遇到过一样的问题,解决方法就是把contentMode属性设置成更合适的值,像这样:
1
2
|
//设置内容的显示方式为适应
view.contentMode = UIViewContentModeScaleAspectFit;
|
这个方法基本和咱们遇到的状况的解决方法已经接近了(你能够试一下 :) ),不过UIView大多数视觉相关的属性好比contentMode,对这些属性的操做实际上是对对应图层的操做。
CALayer与contentMode对应的属性叫作contentsGravity,可是它是一个NSString类型,而不是像对应的UIKit部分,那里面的值是枚举。contentsGravity可选的常量值有如下一些:
和cotentMode同样,contentsGravity的目的是为了决定内容在图层的边界中怎么对齐,咱们将使用kCAGravityResizeAspect,它的效果等同于UIViewContentModeScaleAspectFit, 同时它还能在图层中等比例拉伸以适应图层的边界。
1
|
self.layerView.layer.contentsGravity = kCAGravityResizeAspect;
|
图2.2 能够看到结果
图2.2 正确地设置contentsGravity的值