ios Xcode 5 和资产目录:如何引用 LaunchImage?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19107543/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Xcode 5 & Asset Catalog: How to reference the LaunchImage?
提问by toblerpwn
I am using Xcode 5's Asset Catalog, and I would like to use my LaunchImage
as the background image of my home view (a pretty common practice to make the transition from 'loading' to 'loaded' look smooth).
我正在使用 Xcode 5 的资产目录,我想使用我的LaunchImage
作为我的主视图的背景图像(一种非常常见的做法,使从“加载”到“加载”的过渡看起来很平滑)。
I would like to use the same entry in the Asset Catalog to save space and not have to replicate the image in two different Image Sets.
我想在资产目录中使用相同的条目来节省空间,而不必在两个不同的图像集中复制图像。
However, calling:
但是,调用:
UIImage *image = [UIImage imageNamed:@"LaunchImage"]; //returns nil
回答by Pichirichi
This is the (almost) complete list of the LaunchImage (excluding the iPad images with no status bar):
这是 LaunchImage 的(几乎)完整列表(不包括没有状态栏的 iPad 图像):
- [email protected]
- [email protected]
- LaunchImage-700-Landscape@2x~ipad.png
- LaunchImage-700-Landscape~ipad.png
- LaunchImage-700-Portrait@2x~ipad.png
- LaunchImage-700-Portrait~ipad.png
- [email protected]
- LaunchImage-Landscape@2x~ipad.png
- LaunchImage-Landscape~ipad.png
- LaunchImage-Portrait@2x~ipad.png
- LaunchImage-Portrait~ipad.png
- LaunchImage.png
- [email protected]
- [email protected] (iPhone 6)
- [email protected] (iPhone 6 Plus Portrait)
- [email protected] (iPhone 6 Plus Landscape)
- [email protected] (iPhone X Portrait)
- [email protected] (iPhone X Landscape)
- [email protected]
- [email protected]
- LaunchImage-700-Landscape@2x~ipad.png
- LaunchImage-700-Landscape~ipad.png
- LaunchImage-700-Portrait@2x~ipad.png
- LaunchImage-700-Portrait~ipad.png
- [email protected]
- LaunchImage-Landscape@2x~ipad.png
- LaunchImage-Landscape~ipad.png
- LaunchImage-Portrait@2x~ipad.png
- LaunchImage-Portrait~ipad.png
- 启动图片.png
- [email protected]
- [email protected] (iPhone 6)
- [email protected] (iPhone 6 Plus 人像)
- [email protected] (iPhone 6 Plus Landscape)
- [email protected](iPhone X 人像)
- [email protected] (iPhone X Landscape)
回答by Cherpak Evgeny
- (NSString *)splashImageNameForOrientation:(UIInterfaceOrientation)orientation {
CGSize viewSize = self.view.bounds.size;
NSString* viewOrientation = @"Portrait";
if (UIDeviceOrientationIsLandscape(orientation)) {
viewSize = CGSizeMake(viewSize.height, viewSize.width);
viewOrientation = @"Landscape";
}
NSArray* imagesDict = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"UILaunchImages"];
for (NSDictionary* dict in imagesDict) {
CGSize imageSize = CGSizeFromString(dict[@"UILaunchImageSize"]);
if (CGSizeEqualToSize(imageSize, viewSize) && [viewOrientation isEqualToString:dict[@"UILaunchImageOrientation"]])
return dict[@"UILaunchImageName"];
}
return nil;
}
回答by JosephH
The LaunchImages are special, and aren't actually an asset catalog on the device. If you look using iFunBox/iExplorer/etc (or on the simulator, or in the build directory) you can see the final names, and then write code to use them - eg. for an iOS7-only iPhone-only project, this will set the right launch image:
LaunchImages 很特别,实际上并不是设备上的资产目录。如果您查看使用 iFunBox/iExplorer/etc(或在模拟器上,或在构建目录中),您可以看到最终名称,然后编写代码来使用它们 - 例如。对于仅限 iOS7 的仅限 iPhone 的项目,这将设置正确的启动图像:
NSString *launchImage;
if ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) &&
([UIScreen mainScreen].bounds.size.height > 480.0f)) {
launchImage = @"LaunchImage-700-568h";
} else {
launchImage = @"LaunchImage-700";
}
[self.launchImageView setImage:[UIImage imageNamed:launchImage]];
I put this into viewDidLoad.
我把它放到 viewDidLoad 中。
This isn't really ideal, it would be great if Apple would give us a nice API to do this.
这不是很理想,如果 Apple 能给我们一个很好的 API 来做到这一点,那就太好了。
回答by nonamelive
My app currently only supports iOS 7 and later.
我的应用目前仅支持 iOS 7 及更高版本。
This is how I reference the launch image from the asset catalog:
这是我从资产目录中引用启动图像的方式:
NSDictionary *dict = @{@"320x480" : @"LaunchImage-700",
@"320x568" : @"LaunchImage-700-568h",
@"375x667" : @"LaunchImage-800-667h",
@"414x736" : @"LaunchImage-800-Portrait-736h"};
NSString *key = [NSString stringWithFormat:@"%dx%d",
(int)[UIScreen mainScreen].bounds.size.width,
(int)[UIScreen mainScreen].bounds.size.height];
UIImage *launchImage = [UIImage imageNamed:dict[key]];
You can add more key value pairs if you want to support older iOS versions.
如果您想支持较旧的 iOS 版本,您可以添加更多键值对。
回答by vilanovi
Here a category on UIImage based on the solution provided by Cherpak Evgeny above.
这里是基于上面 Cherpak Evgeny 提供的解决方案的 UIImage 类别。
UIImage+SplashImage.h:
UIImage+SplashImage.h:
#import <UIKit/UIKit.h>
/**
* Category on `UIImage` to access the splash image.
**/
@interface UIImage (SplashImage)
/**
* Return the name of the splash image for a given orientation.
* @param orientation The interface orientation.
* @return The name of the splash image.
**/
+ (NSString *)si_splashImageNameForOrientation:(UIInterfaceOrientation)orientation;
/**
* Returns the splash image for a given orientation.
* @param orientation The interface orientation.
* @return The splash image.
**/
+ (UIImage*)si_splashImageForOrientation:(UIInterfaceOrientation)orientation;
@end
UIImage+SplashImage.m:
UIImage+SplashImage.m:
#import "UIImage+SplashImage.h"
@implementation UIImage (SplashImage)
+ (NSString *)si_splashImageNameForOrientation:(UIInterfaceOrientation)orientation
{
CGSize viewSize = [UIScreen mainScreen].bounds.size;
NSString *viewOrientation = @"Portrait";
if (UIDeviceOrientationIsLandscape(orientation))
{
viewSize = CGSizeMake(viewSize.height, viewSize.width);
viewOrientation = @"Landscape";
}
NSArray* imagesDict = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"UILaunchImages"];
for (NSDictionary *dict in imagesDict)
{
CGSize imageSize = CGSizeFromString(dict[@"UILaunchImageSize"]);
if (CGSizeEqualToSize(imageSize, viewSize) && [viewOrientation isEqualToString:dict[@"UILaunchImageOrientation"]])
return dict[@"UILaunchImageName"];
}
return nil;
}
+ (UIImage*)si_splashImageForOrientation:(UIInterfaceOrientation)orientation
{
NSString *imageName = [self si_splashImageNameForOrientation:orientation];
UIImage *image = [UIImage imageNamed:imageName];
return image;
}
@end
回答by Anthony Scott
@codeman's answer updated for Swift 1.2:
@codeman 为 Swift 1.2 更新了答案:
func splashImageForOrientation(orientation: UIInterfaceOrientation, size: CGSize) -> String? {
var viewSize = size
var viewOrientation = "Portrait"
if UIInterfaceOrientationIsLandscape(orientation) {
viewSize = CGSizeMake(size.height, size.width)
viewOrientation = "Landscape"
}
if let imagesDict = NSBundle.mainBundle().infoDictionary as? [String: AnyObject] {
if let imagesArray = imagesDict["UILaunchImages"] as? [[String: String]] {
for dict in imagesArray {
if let sizeString = dict["UILaunchImageSize"], let imageOrientation = dict["UILaunchImageOrientation"] {
let imageSize = CGSizeFromString(sizeString)
if CGSizeEqualToSize(imageSize, viewSize) && viewOrientation == imageOrientation {
if let imageName = dict["UILaunchImageName"] {
return imageName
}
}
}
}
}
}
return nil
}
To call it, and to support rotation for iOS 8:
调用它,并支持 iOS 8 的旋转:
override func viewWillAppear(animated: Bool) {
if let img = splashImageForOrientation(UIApplication.sharedApplication().statusBarOrientation, size: self.view.bounds.size) {
backgroundImage.image = UIImage(named: img)
}
}
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
let orientation = size.height > size.width ? UIInterfaceOrientation.Portrait : UIInterfaceOrientation.LandscapeLeft
if let img = splashImageForOrientation(orientation, size: size) {
backgroundImage.image = UIImage(named: img)
}
}
Just what I needed, thanks!
正是我需要的,谢谢!
回答by codeman
Swift version of Cherpak Evgeny's answer:
Cherpak Evgeny 答案的 Swift 版本:
func splashImageForOrientation(orientation: UIInterfaceOrientation) -> String {
var viewSize = self.view.bounds.size
var viewOrientation = "Portrait"
if UIInterfaceOrientationIsLandscape(orientation) {
viewSize = CGSizeMake(viewSize.height, viewSize.width)
viewOrientation = "Landscape"
}
let imagesDict = NSBundle.mainBundle().infoDictionary as Dictionary<NSObject,AnyObject>!
let imagesArray = imagesDict["UILaunchImages"] as NSArray
for dict in imagesArray {
let dictNSDict = dict as NSDictionary
let imageSize = CGSizeFromString(dictNSDict["UILaunchImageSize"] as String)
if CGSizeEqualToSize(imageSize, viewSize) && viewOrientation == (dictNSDict["UILaunchImageOrientation"] as String) {
return dictNSDict["UILaunchImageName"] as String
}
}
return ""
}
回答by zaheer
I just wrote a general method to get the splash image name for iPhone and iPad (Landscape, Portrait), It worked for me, Hope It helps you as well. I wrote this with help of other SO answers, thanks @Pichirichi for whole list.
我刚刚写了一个通用方法来获取 iPhone 和 iPad(横向、纵向)的初始图像名称,它对我有用,希望它也能帮助你。我在其他 SO 答案的帮助下写了这篇文章,感谢 @Pichirichi 提供整个列表。
+(NSString*)getLaunchImageName
{
NSArray* images= @[@"LaunchImage.png", @"[email protected]",@"[email protected]",@"[email protected]",@"[email protected]",@"LaunchImage-700-Portrait@2x~ipad.png",@"LaunchImage-Portrait@2x~ipad.png",@"LaunchImage-700-Portrait~ipad.png",@"LaunchImage-Portrait~ipad.png",@"LaunchImage-Landscape@2x~ipad.png",@"LaunchImage-700-Landscape@2x~ipad.png",@"LaunchImage-Landscape~ipad.png",@"LaunchImage-700-Landscape~ipad.png"];
UIImage *splashImage;
if ([self isDeviceiPhone])
{
if ([self isDeviceiPhone4] && [self isDeviceRetina])
{
splashImage = [UIImage imageNamed:images[1]];
if (splashImage.size.width!=0)
return images[1];
else
return images[2];
}
else if ([self isDeviceiPhone5])
{
splashImage = [UIImage imageNamed:images[1]];
if (splashImage.size.width!=0)
return images[3];
else
return images[4];
}
else
return images[0]; //Non-retina iPhone
}
else if ([[UIDevice currentDevice] orientation]==UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown)//iPad Portrait
{
if ([self isDeviceRetina])
{
splashImage = [UIImage imageNamed:images[5]];
if (splashImage.size.width!=0)
return images[5];
else
return images[6];
}
else
{
splashImage = [UIImage imageNamed:images[7]];
if (splashImage.size.width!=0)
return images[7];
else
return images[8];
}
}
else
{
if ([self isDeviceRetina])
{
splashImage = [UIImage imageNamed:images[9]];
if (splashImage.size.width!=0)
return images[9];
else
return images[10];
}
else
{
splashImage = [UIImage imageNamed:images[11]];
if (splashImage.size.width!=0)
return images[11];
else
return images[12];
}
}
}
Other utility methods are
其他实用方法是
+(BOOL)isDeviceiPhone
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
return TRUE;
}
return FALSE;
}
+(BOOL)isDeviceiPhone4
{
if ([[UIScreen mainScreen] bounds].size.height==480)
return TRUE;
return FALSE;
}
+(BOOL)isDeviceRetina
{
if ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] &&
([UIScreen mainScreen].scale == 2.0)) // Retina display
{
return TRUE;
}
else // non-Retina display
{
return FALSE;
}
}
+(BOOL)isDeviceiPhone5
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone && [[UIScreen mainScreen] bounds].size.height>480)
{
return TRUE;
}
return FALSE;
}
回答by Adam
Following @Pichirich's answer, I referenced my launchimage in InterfaceBuilder as:
按照@Pichirich 的回答,我在 InterfaceBuilder 中引用了我的启动图像:
"LaunchImage.png"
“启动图像.png”
...and with Xcode 5.0.2, it's automatically plucking the appropriate image straight out of the Asset Catalog.
...使用 Xcode 5.0.2,它会自动直接从资产目录中提取适当的图像。
This is what I'd expect - except for Apple's viciously nasty move of silently renaming "Default.png" to "LaunchImage.png" :)
这就是我所期望的 - 除了 Apple 将“Default.png”默默地重命名为“LaunchImage.png”的恶毒举动:)
回答by Vladimír Slavík
In the documentationthere is clearly stated:
在文档中有明确的说明:
"Each set in an asset catalog has a name. You can use that nameto programmatically load any individual image contained in the set. To load an image, call the UIImage:ImageNamed:method, passing the name of the set that contains the image."
“资产目录中的每个集合都有一个名称。您可以使用该名称以编程方式加载集合中包含的任何单个图像。要加载图像,请调用UIImage:ImageNamed:方法,传递包含图像的集合的名称.”
Using Pichirichi's list helps to solve this inconsistency.
使用 Pichirichi 的列表有助于解决这种不一致。