iOS:使用 LaunchImage 作为应用背景

Posted

技术标签:

【中文标题】iOS:使用 LaunchImage 作为应用背景【英文标题】:iOS: Using LaunchImage as app background 【发布时间】:2014-08-24 14:54:24 【问题描述】:

这可能没有故障吗?

我的 Xcode 项目在资产(又名 Images.xcassets)中定义了一个启动图像,包括。所有支持的尺寸和方向。由于我想在初始视图中使用相同的图像作为背景,因此我将其添加到视图控制器中作为背景:

    view.layer.contents = UIImage(named:"LaunchImage").CGImage;

但是,当启动屏幕切换到初始视图时,会出现明显的故障,因为视图中设置的背景图像会拉伸。此外,当我旋转设备时,图像会拉伸。

设备旋转时发生的拉伸似乎是合理的,因为显然资产目录图像中的其他图像尺寸/方向在设置为背景图像时不会被视为(我的猜测)。

但是在启动屏幕和我的初始视图之间发生的拉伸似乎很奇怪,因为两者应该具有相同的大小。

当设备方向改变时,是否有任何久经考验的程序可以让 bg 图像始终适应纵横比?这甚至可能与(多尺寸)启动图像有关吗?


更新:

添加背景图像的一种可能方法是将UIImageView 放置在背景中(在所有其他视图之后)并将图像加载到其中。该解决方案解决了设备方向问题,对我来说没问题,但还有另一个问题:它加载了错误的图像尺寸。如果我在 iPad2 emu 上对其进行测试,它应该使用名为 Default~ipad~nostatusbar.png 的图像,但如果我检查 UIImage 的大小,它只有 320x480 像素,所以它显然使用了名为默认.png

我只能通过 Images.xcassets 中定义的名称加载启动图像。如果我尝试使用物理文件名(例如 Default.png)创建 UIImage,则 bg 将保持黑色。

所以问题是:如何让 ios 从 Images.xcassets 中的 LaunchImage 中选择正确的图像大小/方向?

【问题讨论】:

【参考方案1】:

为了完全解决这个问题,这是我的 Daij-Djan 代码的 Swift 版本。它还在评论块中列出了数量惊人的不同启动图像版本。有一些对我自己的 util lib (EnvUtil) 的调用,但这是另一回事,大多数用户可以弄清楚如何获取所需的变量。

/**
   Returns the default image (launch image) of the application with regard to the screen size and orientation.

   Default.png                               | LaunchImage.png                       |  320 x 480  | iPhone 4 Low Res.
   Default@2x.png                            | LaunchImage@2x.png                    |  640 x 960  | iPhone 4
   Default@2x.png                            | LaunchImage-700@2x.png                |  640 x 960  | iPhone 4 iOS7
   Default-568h@2x.png                       | LaunchImage-568h@2x.png               |  640 x 1136 | iPhone 5
   Default-568h@2x.png                       | LaunchImage-700-568h@2x.png           |  640 x 1136 | iPhone 5
   Default~ipad.png                          | LaunchImage-Portrait~ipad.png         |  768 x 1004 | iPad Portrait
   Default~ipad~nostatusbar.png              | LaunchImage-700-Portrait~ipad.png     |  768 x 1024 | iPad Portrait FS
   Default~ipad~landscape.png                | LaunchImage-Landscape~ipad.png        | 1024 x 748  | iPad Landscape
   Default~ipad~landscape~nostatusbar.png    | LaunchImage-700-Landscape~ipad.png    | 1024 x 768  | iPad Landscape FS
   Default~ipad@2x.png                       | LaunchImage-Portrait@2x~ipad.png      | 1536 x 2008 | iPad Portrait Retina
   Default~ipad~nostatusbar@2x.png           | LaunchImage-700-Portrait@2x~ipad.png  | 1536 x 2048 | iPad Portrait Retina FS
   Default~ipad~landscape@2x.png             | LaunchImage-Landscape@2x~ipad.png     | 2048 x 1496 | iPad Landscape Retina
   Default~ipad~landscape~nostatusbar@2x.png | LaunchImage-700-Landscape@2x~ipad.png | 2048 x 1536 | iPad Landscape Retina FS
 */
public class func getDefaultImage() -> UIImage

    var fileName:String = "LaunchImage";
    let osVersion:String = EnvUtil.systemVersionMajor() > 6 ? "700" : "";
    let scale:String = EnvUtil.isRetina() ? "@2x" : "";
    let div:String = osVersion.length > 0 ? "-" : "";

    if (EnvUtil.isPad())
    
        let orientation:String = EnvUtil.isPortraitOrientation() ? "Portrait" : "Landscape";
        fileName += "-" + osVersion + div + orientation + scale + "~ipad";
    
    else
    
        if (CGRectGetHeight(UIScreen.mainScreen().bounds) > 480.0)
        
            /* iPhone 5. */
            fileName += "-" + osVersion + div + "568h@2x";
        
        else
        
            /* iPhone 4 with iOS7? */
            fileName += div + osVersion + scale;
        
    

    fileName += ".png";
    //Log.debug(fileName);

    return UIImage(named: fileName);

【讨论】:

【参考方案2】:

我在 objC 中有一个 UIImage+DefaultImage [ios] 类别允许这样做。应该很容易移植到 swift 扩展

#import <UIKit/UIKit.h>

@interface UIImage (DefaultImage)

// uses statusbar orientation
+ (UIImage *)defaultImage;

//uses given orientation
+ (UIImage *)defaultImageForOrientation:(UIInterfaceOrientation)orient;

@end

@implementation UIImage (DefaultImage)

+ (UIImage *)defaultImage 
    return [self defaultImageForOrientation:[[UIApplication sharedApplication] statusBarOrientation]];


+ (UIImage  *)defaultImageForOrientation:(UIInterfaceOrientation)orient 
    // choose the correct launch image for orientation, device and scale
    NSMutableString *launchImageName = [[NSMutableString alloc] initWithString:@"Default"];
    BOOL isPad = ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad );
    if ( isPad ) 
        BOOL isLandscape = UIInterfaceOrientationIsLandscape(orient);
        NSString *imageOrientation = (isLandscape) ? @"Landscape" : @"Portrait";

        BOOL isRetina = ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] && [[UIScreen mainScreen] scale] == 2.0);
        NSString *scaleString = (isRetina) ? @"@2x" : @"";

        // Default-Landscape~ipad.png
        // Default-Landscape@2x~ipad.png
        // Default-Portrait~ipad.png
        // Default-Portrait@2x~ipad.png
        launchImageName = [NSMutableString stringWithFormat:@"%@-%@%@.png", launchImageName, imageOrientation, scaleString];       
     else 
        if ( CGRectGetHeight([UIScreen mainScreen].bounds) > 480.f) 
            // Default-568h.png
            launchImageName = [NSMutableString stringWithFormat:@"%@-568h.png", launchImageName];
         else 
            // Default.png
            // Default@2x.png
            launchImageName = [NSMutableString stringWithFormat:@"%@.png", launchImageName];
        
    
    return [UIImage imageNamed:launchImageName];


@end

免责声明:我自己的代码——取自https://github.com/Daij-Djan/DDUtils

【讨论】:

但是这个方法只是把图片文件名组装起来,然后生成一个UIImage。但是如果我尝试指定物理文件名,例如UIImage(named:"Default.png"),已经不行了。它显然不会通过其物理文件名(尽管它存在)找到图像,而是仅使用资产 ID,例如'LaunchImage'。 另一个奇怪的是我的启动图像包含大小的文件,包括。状态栏和没有,例如默认~ipad~nostatusbar.png。但是,您的解决方案根本不考虑这些。 Grml 没关系!我刚刚发现图像文件名在编译过程中发生了变化! UIImage *myImage = [UIImage defaultImage]; 在某些情况下我可能没有覆盖图像 :) -- 我前段时间写过。您可以将其扩展以覆盖这些图像,但这就是要走的路【参考方案3】:

启动图像位于应用程序包中(命名为 default.. ),因此您只需将其加载到 UIImageView 并将该 imageView 添加到您的 UIView。

【讨论】:

这似乎解决了方向拉伸问题,但它选择了错误的图像尺寸。当我在 iPad 模拟器上检查图像的大小时,它显示 320x480,这是不正确的。

以上是关于iOS:使用 LaunchImage 作为应用背景的主要内容,如果未能解决你的问题,请参考以下文章

如何在 React Native 中引用启动图像

iOS iPhone LaunchImage Landscape

Xcode 5和资产目录:如何引用LaunchImage?

iOS、LaunchImage Apple Watch 尺寸和名称

对于 iOS LaunchImage,我需要所有图像吗?

iOS图标(AppIcon)与启动图(LaunchImage)