UIImage加载图片的方式以及Images.xcassets对于加载方法的影响
2017.5.19更新:
- 更新了若干概念的理解
- 调整描述方式,行文更流畅
- 更新了代码示例
- 调整文章结构,使其主题更精炼
创建图片对象
根据是否缓存图数据,有两类创建UIImage
对象的方法可选:
Use the imageNamed:inBundle:compatibleWithTraitCollection: method (or the imageNamed: method) to create an image from an image asset or image file located in your app’s main bundle (or some other known bundle). Because these methods cache the image data automatically, they are especially recommended for images that you use frequently.
-
缓存:
imageNamed:
- 只需传入
文件名.扩展名
即可。 - 可以加载bundle中
任意位置
的图片,包括main bundle中其他bundle的。
- 只需传入
-
imageNamed方法创建对象的步骤如下:
- 根据图片文件名在缓存池中查找图片数据,如存在,则创建对象并返回;
- 如果不存在,则从bundle中加载图片数据,创建对象并返回;
- 如果相应的图片数据不存在,返回nil。
Use the imageWithContentsOfFile: or initWithContentsOfFile: method to create an image object where the initial data is not in a bundle. These methods load the image data from disk each time, so you should not use them to load the same image repeatedly.
- 不缓存:
imageWithContentsOfFile:
- 必须传入图片文件的
全名(全路径+文件名)
。 - 无法加载
Images.xcassets
中的图片。
- 必须传入图片文件的
Images.xcassets
Images.xcassets
在app打包后,以Assets.car
文件的形式出现在bundle中。其作用在于:
自动识别@2x,@3x图片,对内容相同但分辨率不同的图片统一管理。
可以对图片进行
Slicing
(即剪裁和拉伸)。其中的图片资源只能通过UIimage的
imageNamed:
方法加载,通过NSBundle的pathForResource:ofType:
无法获得图片路径。适合存放系统常用的,占用内存小的图片资源。
只支持png / jpeg,不支持诸如gif等其他图片格式;使用UIimage的
imageNamed:
加载时,只需提供文件名,不需提供扩展名。小心项目中的同名图片,很有可能造成
异常和bug
。例如:两个同名图片,一个在Assets.xcassets中被sliced
,另一个没有。则系统sliced
图片。从其它项目拖拽图片
时也要小心,如果这个图片在上一个项目中sliced
过,如果连同相应的Contents.json
一起拷贝,则处理效果会被保留
。-
从别的的地方加载图片,必须在文件名后加扩展名,例如:
// pic.jpg处于根目录下 [UIImage imageNamed:@"pic"]; // 错误,图片未能正确加载 [UIImage imageNamed:@"pic.jpg"]; // 正确
从其他Bundle中加载资源
-
从main bundle中其他bundle加载资源,可以分为四步:
- 在main bundle中找到特定bundle。
- 载入bundle,即创建bundle对象。
- 从bundle中获取资源路径。注意,如果资源位于次级目录,则必须指明路径。
- 通过路径创建对象。
例如,如下代码从app bundle根目录下的另一个bundle中获取一张图片。
- (void)viewDidLoad {
[super viewDidLoad];
// 1. 在main bundle中找到特定bundle
NSString *sampleBundlePath = [[NSBundle mainBundle] pathForResource:@"SampleBundle.bundle" ofType:nil];
// 2. 载入bundle,即创建bundle对象
NSBundle *sampleBundle = [NSBundle bundleWithPath:sampleBundlePath];
// 3. 从bundle中获取资源路径
// 注意这里的图片位于通用资源目录下的Images二级目录,相对路径要明确这种关系
NSString *pic1Path = [sampleBundle pathForResource:@"pic1.png" ofType:nil];
// 4. 通过路径创建对象
UIImage *image = [UIImage imageWithContentsOfFile:pic1Path];
}
- 更多关于bundle的信息,可以参考笔记@Bundle Programming Guide。