iPhone:使用尺寸类旋转设备时更改背景图像

Posted

技术标签:

【中文标题】iPhone:使用尺寸类旋转设备时更改背景图像【英文标题】:iPhone : changing background image when rotating device using size classes 【发布时间】:2015-09-29 10:48:28 【问题描述】:

我放置了一张需要填满 iPhone 屏幕的背景图片。在纵向视图中很好,但是当我旋转设备时,顶部会被裁剪,这是我不想要的。 最好的似乎是纵向视图的图像和横向视图的图像。 我尝试使用尺寸等级,为紧凑型 W 和任何 H 分配 1 个图像,为任何 W 和紧凑型 H 分配 1 个图像。我无法使其工作。 我正在使用 Xcode 6.3 和 swift 1.2。 我使用 ios 8 Essentials (Neil Smyth) 第 24 章中的说明制作了另一个应用程序,但它不起作用。我下载了文件“universal_images”,以为我做错了什么,但它也不起作用。

【问题讨论】:

【参考方案1】:

这是我问题的答案。

1 - 我在 Supporting files 中添加了两张背景图片(一张横向版本和一张纵向版本),位于我命名为“images”的组中(不是必需的,但更整洁)。

2 - 在 Main.storyboard 中,我添加了一个视图(通过右下角的对象库),它出现在视图控制器场景中已经存在的视图中。

3 - 在该视图中,我放置了一个图像视图,然后在编辑器 -> 图像视图 -> 图像中选择了纵向图像文件。视图->模式->要填充的方面

4 - 我通过 pin 菜单 0 底部、顶部、左侧、右侧向容器视图和图像视图添加约束。

5 - 在 ViewController.swift 类中的 ViewController: UIViewController …… 我添加了以下代码:

 override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) 
    if (toInterfaceOrientation.isLandscape) 
        println("Landscape");
        background.image = UIImage (named: "BeethovenH.png")
    
    else 
        println("Portrait");
        background.image = UIImage (named: "BeethovenV.png")
    

效果很好。 感谢您的帮助。

【讨论】:

【参考方案2】:

我总是使用两张图片:一张用于纵向,一张用于横向,并且针对不同的目标具有不同的分辨率。这是确保您的背景在具有不同纵横比的不同设备上看起来正确的最佳方式。

我总是将背景设置为包含在单独 UIView 中的 UIImageView。向所有边添加约束以将容器视图和图像视图固定到边缘。这可确保图像自动填充纵向和横向屏幕。

我有以下方法来设置给定方向的背景。它依赖于工厂类来加载适当的图像。加载背景比普通图像需要更多的努力,因为尺寸等级不会告诉你任何关于纵横比的信息。将MyImageFactory 替换为您用于加载相应图像的任何代码。

- (void) setBackgroundImage:(UIInterfaceOrientation) orientation
    if (orientation == UIInterfaceOrientationLandscapeLeft ||
        orientation == UIInterfaceOrientationLandscapeRight)
    
        NSLog(@"Setting background to landscape");
        [self.backgroundImageView setImage:[MyImageFactory backgroundImageLandscape]];
    
    else
        NSLog(@"Setting background to Portrait");
        [self.backgroundImageView setImage:[MyImageFactory backgroundImage]];
    

调用viewWillAppear中的背景设置方法,将背景初始化为启动方向,如下:

- (void) viewWillAppear:(BOOL)animated

    [super viewWillAppear:animated];

    // Set the background image
    [self setBackgroundImage:self.interfaceOrientation];

最后要处理旋转,重写旋转方法如下:

- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
    [self setBackgroundImage:toInterfaceOrientation];

    // Do anything else which is rotation specific.

在 iOS7 到 iOS9 上运行良好。

【讨论】:

谢谢罗里。我会尝试快速(不容易)翻译您的代码并回复您。 “我对不同的目标有不同的分辨率”。你的意思是你使用 Images.xcassets 中的图像集? @Castafiore Image.xcassets 用处不大,因为它只处理分辨率而不是纵横比。您可以通过只为每个设备宽高比执行所需的最高分辨率并让 UIImageView 缩小图像数量来减少图像数量。您可能会发现以下关于实际图像的有用讨论:***.com/questions/19410066/… 我通过link将代码从Objective C“翻译”到Swift,但发现一个主要障碍是错误“interfaceOrientation is deprecated in iOS version 8”,但从那里我能够找到我的问题的答案。我把代码放在下面 @Castafiore 我认为你现在可以使用interfaceOrientation,因为它会存在一段时间。基于大小类的工作不太适合的一件事是背景。约束等都非常适合移动固定大小的对象布局。但是,背景图像必须是正确的方面,否则它看起来是错误的/被压扁等......如果不推荐使用的属性让您担心,您可以通过使用当前屏幕边界来计算方面并通过该机制加载适当的图像。【参考方案3】:

我想这样做,但我花了很长时间才找到解决方案的 ios 11/swift 4 版本,所以我想我会在这里提供它。您遵循上面答案中给出的所有步骤,但代码是:

 func changeBackground() 
     //iPads etc
   if traitCollection.horizontalSizeClass == .regular
    background.image = UIImage(named: "beethovenV.png")
   
    else   
            //compact width - most iPhones in portrait
           background.image = UIImage(named: "beethovenV.png")
            //iphone in landscape
           if traitCollection.verticalSizeClass == .compact
             background.image = UIImage(named: "beethovenH.png")
            
            



override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) 
super.traitCollectionDidChange(previousTraitCollection)
changeBackground()

【讨论】:

【参考方案4】:

您需要做简单的 2 个步骤 1.) 选择尺寸等级 any,any 它将在 ipad 和 iphone 的所有设备的纵向和横向模式下运行。

2.) 使用 autolayout 并设置约束,如截图

它会正常工作的。谢谢

【讨论】:

以上是关于iPhone:使用尺寸类旋转设备时更改背景图像的主要内容,如果未能解决你的问题,请参考以下文章

背景图像/导航栏图像 iOS 的正确尺寸

更改设备方向时如何为uiimageview设置动画

在情节提要中更改 iphone 4 和 iphone 5 之间的背景图像?

UIView 背景图像在设备旋转时不缩放

设备上的图像尺寸错误

iOS应用程序的背景图像的正确尺寸是多少