资产目录中的横向与纵向背景图像

Posted

技术标签:

【中文标题】资产目录中的横向与纵向背景图像【英文标题】:Landscape vs. Portrait background image in Asset Catalog 【发布时间】:2014-09-24 20:43:01 【问题描述】:

我有一个用例似乎落入了资产目录和大小类别之间的裂缝中。我的 Universal 应用需要横向和纵向方向不同的全屏背景图片,并且横向仅支持 iPad 和 iPhone 6。

由于我无法将横向图像添加到新图像集的资产目录中,因此我当前的解决方案如下所示(支持 ios 7 和 8):

// permit landscape mode only for iPads & iPhone 6 (would prefer to use size classes, but...?)
override func shouldAutorotate() -> Bool 
    let size = view.frame.size
    let maxv = max(size.width, size.height)
    return ((maxv > 700.0) || (maxv == 512.0)) ? true : false


// this will be triggered only for iOS 7, as long as viewWillTransitionToSize:withTransitionCoordinator: is also implemented!
override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) 
    adjustToOrientation(toInterfaceOrientation)


// this will be triggered only for iOS 8
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) 

    let orientation = UIApplication.sharedApplication().statusBarOrientation

    // need to reverse the sense of the orientation here; Application still has the previous orientation
    switch orientation 
        case .Portrait, .PortraitUpsideDown:
            adjustToOrientation(.LandscapeLeft)
        case .LandscapeLeft, .LandscapeRight:
            adjustToOrientation(.Portrait)
        default:
            adjustToOrientation(.Portrait)
    



func adjustToOrientation(newInterfaceOrientation: UIInterfaceOrientation) 

    let size = view.frame.size

    // rotation already permitted only for iPad & iPhone 6, but need to know which one (size classes useless here?)
    switch (max(size.width, size.height)) 
        case 1024.0:
            if UIInterfaceOrientationIsLandscape(newInterfaceOrientation) 
                backgroundImage.image = UIImage(named: "Background-Landscape@2x~ipad.png")
             else 
                backgroundImage.image = UIImage(named: "Background@2x~ipad.png")
            
        case 736.0:
            if UIInterfaceOrientationIsLandscape(newInterfaceOrientation) 
                backgroundImage.image = UIImage(named: "Background-Landscape@3x~iphone.png")
             else 
                backgroundImage.image = UIImage(named: "Background@3x~iphone.png")
            
        case 512.0:
            if UIInterfaceOrientationIsLandscape(newInterfaceOrientation) 
                backgroundImage.image = UIImage(named: "Background-Landscape~ipad.png")
             else 
                backgroundImage.image = UIImage(named: "Background~ipad.png")
            
        default:
            break
    


这可行,但似乎很脆弱。在实际处于横向模式之前,是否有更正确的方法可以将设备识别为支持横向常规尺寸类的设备?或者我错过了为图像集指定景观等效项的某种方式?

【问题讨论】:

【参考方案1】:

您可以在资产目录中使用尺寸类别,也可以有两个图像集:一个用于纵向,一个用于陆地空间模式。然后您可以按资产名称访问图像。这会稍微减少你的代码。但我建议尽可能考虑使用尺寸等级。

【讨论】:

谢谢,Vitaly...事实上,在观看了 WWDC14 关于特征集合的讨论(使用 UIKit 构建自适应应用程序)之后,我已经消除了大部分代码。 UIImage 确实可以识别图像集中那些额外的尺寸类,并随着特征集合的变化自动调整。我将图像资源的 Width 属性设置为 Any+Regular 并添加了几个横向图像,就是这样。 那么,没有办法在资产目录中为新图像集添加横向图像吗? @arh 抱歉回复晚了。您可以为不同的尺寸类别添加不同的图像。因此,如果您的横向和纵向模式具有不同的尺寸等级,您将获得不同的图像,但是当横向和纵向模式使用相同的尺寸等级(如在 iPad 上)时,您将无法使用尺寸等级为此类模式使用不同的图像。如果您确实需要为横向和纵向模式使用不同的图像,您必须考虑为此类模式使用不同的图像集,或者根本不为此类图像使用图像集。【参考方案2】:

所以最终的解决方案是:

-将图像资源的 Width 属性设置为 Any+Regular,并为 iPhone 6+ 和 iPad 添加了几个横向图像,其余的由 UIImage 自动完成

-在 iOS 7 和 iOS 8 中只允许这两个设备旋转的更优雅的方式:

override func shouldAutorotate() -> Bool 
    let scale = UIScreen.mainScreen().scale
    let idiom = UIDevice.currentDevice().userInterfaceIdiom
    return ((idiom == .Pad) || (scale > 2.0)) ? true : false

所以上面所有的代码都只需要 5 行代码!

【讨论】:

唉,毕竟不是一个完美的解决方案;似乎 UIImage 的特征收集支持无法区分 iPad 的横向和纵向模式;模拟器屏幕截图显示横向图像在两个方向上都用于 iOS 8,而在 iOS 7 上使用纵向图像!?!

以上是关于资产目录中的横向与纵向背景图像的主要内容,如果未能解决你的问题,请参考以下文章

当方向从横向更改为纵向时,UInavigationbar 背景图像无法正确调整大小

LaunchScreen.storyboard 中 iPad 启动画面的不同背景图像,用于横向和纵向模式

当我从纵向模式更改为横向时,按钮背景图像消失

如何使用swift在iOS中为活动设置两种不同大小的背景图像作为横向和纵向模式

在css中设置图片的背景图,怎么设置图片纵向拉伸

如何将位图图像横向设置为纵向