iOS 8引入了一个UIImageAsset类,其中包含一个方法registerImage:withTraitCollection:
。我该如何使用这个类?
iOS 8引入了一个UIImageAsset类,其中包含一个方法registerImage:withTraitCollection:
。我该如何使用这个类?
通常情况下,您不需要这么做。相反,您将使用一个资源目录(asset catalog)。UIImageAsset在iOS 8中只是资源目录中图像集的底层机制。
例如,在iOS 8中,资源目录可以区分用于不同尺寸类别情况下的图像版本,使用“宽度”和“高度”弹出菜单指定不同的尺寸类别可能性。然后,在您的界面中使用来自资源目录的图像时,正确的事情会自动发生。如果我们在iPhone上将应用程序旋转为横向方向,并且图像集中有任意高度和紧凑高度的替代版本,则使用紧凑高度版本。而且这些功能是实时的;如果应用程序从横向旋转到纵向,并且图像集中有任意高度和紧凑高度的替代版本,则紧凑高度版本会自动在您的界面中被任意高度版本所替换。
您会注意到我没有提到UIImageAsset。但是,UIImageAsset是底层机制。当通过init(named:)
和其图像集的名称从资源目录中提取图像时,其imageAsset
属性是UIImageAsset。该图像集中的所有图像都可通过UIImageAsset获得;每个图像都有与之关联的特征集合(其traitCollection
),您可以通过调用imageWithTraitCollection:
来向UIImageAsset请求适合于特定特征集合的图像。事实上,这恰恰是界面在为您做什么。在iOS 8中,可以显示图像的界面对象自动具备特征集合知识;它接收到traitCollectionDidChange:
消息并相应地响应。
然而,也可以将图像组合成自己的UIImageAsset。从某种意义上说,这就像在代码中制作资源目录(或至少是图像集)!在此示例中,我将从应用程序包(bundle)中提取两个图像,并将它们配置为在应用程序处于纵向方向时使用一个,在应用程序处于横向方向时使用另一个,自动地:
let tcdisp = UITraitCollection(displayScale: UIScreen.mainScreen().scale)
let tcphone = UITraitCollection(userInterfaceIdiom: .Phone)
let tcreg = UITraitCollection(verticalSizeClass: .Regular)
let tc1 = UITraitCollection(traitsFromCollections: [tcdisp, tcphone, tcreg])
let tccom = UITraitCollection(verticalSizeClass: .Compact)
let tc2 = UITraitCollection(traitsFromCollections: [tcdisp, tcphone, tccom])
let moods = UIImageAsset()
let frowney = UIImage(named:"frowney")
let smiley = UIImage(named:"smiley")
moods.registerImage(frowney, withTraitCollection: tc1)
moods.registerImage(smiley, withTraitCollection: tc2)
之后,如果将frowney
放入接口中——例如,将其交给UIImageView作为其图像,或将其分配为UIButton的图像——当应用程序更改方向时,它会自动与smiley
交替。
不可思议的是,即使没有对frowney
、smiley
或UIImageAsset(moods
)进行持久引用,这个魔法也能起作用。原因是系统缓存了frowney
和smiley
(因为调用了init(named:)
),它们各自保持着对它们注册的UIImageAsset的强引用。