资产目录中的横向与纵向背景图像
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 启动画面的不同背景图像,用于横向和纵向模式