[iOS Animation]-CALayer 显示方式

寄宿图

图片赛过千言万语,界面抵得上千图片 ——Ben Shneiderman git

咱们在第一章『图层树』中介绍了CALayer类并建立了一个简单的有蓝色背景的图层。背景颜色还好啦,可是若是它仅仅是展示了一个单调的颜色未免也太无聊了。事实上CALayer类可以包含一张你喜欢的图片,这一章节咱们未来探索CALayer的寄宿图(即图层中包含的图)。 github

contents属性

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的宿主图层中显示一张图片 图片

图2.1

咱们用这些简单的代码作了一件颇有趣的事情:咱们利用CALayer在一个普通的UIView中显示了一张图片。这不是一个UIImageView,它不是咱们一般用来展现图片的方法。经过直接操做图层,咱们使用了一些新的函数,使得UIView更加有趣了。

contentGravity

你可能已经注意到了咱们的雪人看起来有点。。。胖 ==! 咱们加载的图片并不恰好是一个方的,为了适应这个视图,它有一点点被拉伸了。在使用UIImageView的时候遇到过一样的问题,解决方法就是把contentMode属性设置成更合适的值,像这样:

1
2
//设置内容的显示方式为适应
view.contentMode = UIViewContentModeScaleAspectFit;

这个方法基本和咱们遇到的状况的解决方法已经接近了(你能够试一下 :) ),不过UIView大多数视觉相关的属性好比contentMode,对这些属性的操做实际上是对对应图层的操做。

CALayer与contentMode对应的属性叫作contentsGravity,可是它是一个NSString类型,而不是像对应的UIKit部分,那里面的值是枚举。contentsGravity可选的常量值有如下一些:

  • kCAGravityCenter
  • kCAGravityTop
  • kCAGravityBottom
  • kCAGravityLeft
  • kCAGravityRight
  • kCAGravityTopLeft
  • kCAGravityTopRight
  • kCAGravityBottomLeft
  • kCAGravityBottomRight
  • kCAGravityResize
  • kCAGravityResizeAspect
  • kCAGravityResizeAspectFill

和cotentMode同样,contentsGravity的目的是为了决定内容在图层的边界中怎么对齐,咱们将使用kCAGravityResizeAspect,它的效果等同于UIViewContentModeScaleAspectFit, 同时它还能在图层中等比例拉伸以适应图层的边界。

1
self.layerView.layer.contentsGravity = kCAGravityResizeAspect;

图2.2 能够看到结果

image

图2.2 正确地设置contentsGravity的值

相关文章
相关标签/搜索