iPad横屏和竖屏使用不同的布局,如何使用Size Class实现?

27
如何使用大小类(Size class)设计iPad横向和纵向屏幕具有不同布局的界面。
我只能找到w-regular和h-regular用于两种方向。例如:我需要使用大小类在纵向时垂直对齐2个视图,在横向时水平对齐。

1
对于 iPhone,可以使用 Size Class 创建两个不同方向的布局。那么如何在 iPad 上使用 Size Class 和 Autolayout 实现这一点呢? - Harish Kumar Kailas
你找到解决方案了吗?我也有同样的问题。 - cmii
6
实际上,这是一个具体的问题。苹果并没有设计尺寸类别来启用iPad横向特定的尺寸类别,这让我完全无法理解,因为这样你就必须在代码中手动处理横向问题。我不同意一些通过对尺寸类别系统进行修改的方法。直接在代码中处理它就可以了。 - n8tr
如果iPad的横向和纵向设计完全不同,应该采用哪种方式更好?我们需要使用AutoLayout还是两个不同的故事板? - Sandip Patel - SM
4个回答

6
最终,我找到了一个解决方案:
if traitCollection.verticalSizeClass == .Regular && traitCollection.horizontalSizeClass == .Regular {

     var orientation:UIInterfaceOrientation = UIApplication.sharedApplication().statusBarOrientation;
     if orientation == UIInterfaceOrientation.LandscapeLeft || orientation == UIInterfaceOrientation.LandscapeRight {
            // orientation is landscape


     }  else {
            // orientation is portrait

     }
}

6

苹果似乎打算将两种iPad方向视为相同的 - 但正如我们中的许多人发现的那样,有非常合理的设计原因要在iPad纵向和iPad横向上变化UI布局。

然而,请参见此答案以另一种方法来适应大小类以满足我们的需求: https://dev59.com/Fl8d5IYBdhLWcg3wmDOf#28268200


我正在开发通用应用程序,在其中尝试了您的方法。它在iPad上运行良好,但当我为w:Any,h:Any设置约束时,出现了“无法同时满足约束条件”的错误。 - Peer Mohamed Thabib

5

对于 Swift 3,代码如下:

override func overrideTraitCollection(forChildViewController childViewController: UIViewController) -> UITraitCollection? {
    if UI_USER_INTERFACE_IDIOM() == .pad &&
        view.bounds.width > view.bounds.height {

        let collections = [UITraitCollection(horizontalSizeClass: .regular),
                           UITraitCollection(verticalSizeClass: .compact)]
        return UITraitCollection(traitsFrom: collections)

    }

    return super.overrideTraitCollection(forChildViewController: childViewController)
}

在iPad设备的横屏模式下,它将使用wRhC而不是wRhR。 将此代码放入基础视图控制器中,即此规则将适用于由此控制器呈现的所有控制器。 您可以在此处添加任何其他条件...例如,如果您希望此规则仅在特定视图控制器中起作用,则您的if运算符将如下所示:

    if UI_USER_INTERFACE_IDIOM() == .pad &&
        childViewController is YourSpecificViewController &&
        view.bounds.width > view.bounds.height {

        let collections = [UITraitCollection(horizontalSizeClass: .regular),
                           UITraitCollection(verticalSizeClass: .compact)]
        return UITraitCollection(traitsFrom: collections)

    }

1
这样做可能会带来意想不到的后果。例如,如果此视图控制器显示另一个模态视图控制器作为表单表格,它将像在 iPhone 上一样全屏显示 - 竖屏模式下 - 这可能不是您想要的。此外,在打开的同时,如果您旋转到横向模式,它将返回到非全屏状态,并且在您旋转回纵向模式时将保持该状态。这不是一种愉快的体验。 - Michael

2
Swift 4
override func overrideTraitCollection(forChildViewController childViewController: UIViewController) -> UITraitCollection? {
    if UIDevice.current.userInterfaceIdiom == .pad && UIDevice.current.orientation.isLandscape {
        return UITraitCollection(traitsFrom:[UITraitCollection(verticalSizeClass: .compact), UITraitCollection(horizontalSizeClass: .regular)])
    }
    return super.overrideTraitCollection(forChildViewController: childViewController)
}

我喜欢创建一个自定义的navigationController子类,然后将storyboard的初始导航控制器设置为该类。你也可以用类似的方法来创建 ViewController
例如:
import UIKit

class NavigationControllerWithTraitOverride: UINavigationController {
    
    // If you make a navigationController a member of this class the descendentVCs of that navigationController will have their trait collection overridden with compact vertical size class if the user is on an iPad and the device is horizontal.
    
    override func overrideTraitCollection(forChildViewController childViewController: UIViewController) -> UITraitCollection? {
        if UIDevice.current.userInterfaceIdiom == .pad && UIDevice.current.orientation.isLandscape {
            return UITraitCollection(traitsFrom:[UITraitCollection(verticalSizeClass: .compact), UITraitCollection(horizontalSizeClass: .regular)])
        }
        return super.overrideTraitCollection(forChildViewController: childViewController)
    }
}

注意:根据 文档,您不应覆盖 traitCollection。
重要提示:请直接使用 traitCollection 属性。不要覆盖它,也不要提供自定义实现。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接