UISplitViewController - 防止在 iPhone 6 plus 上横向拆分

UISplitViewController - prevent splitting in landscape on iPhone 6 plus

我在我的应用程序中使用 UISplitViewController。这在 iPad 上工作得很好,其中主要和次要始终可见,并且在大多数 iPhone 上工作得很好,它就像一个 UINavigationController。

在 iPhone 6+ 和 6S+ 上,拆分视图在纵向中的作用类似于 iPhone,在横向中的作用类似于 iPad。这种景观分裂给我带来了问题,我想避免它。

有什么方法可以防止 UISplitViewController 在 iPhone 6+ 横向中显示主控制器和辅助控制器?我只是想让它显示辅助控制器,就像它对其他 iPhones 所做的一样。

谢谢。

我能够通过子classing UISplitViewController 然后将特征集合覆盖到 return 紧凑的水平尺寸 class 当设备不是 iPad。我知道现在检查界面惯用语是一种失礼,但我不确定该怎么做。

我只是将这个方法添加到我的 UISplitViewController subclass:

-(UITraitCollection *)traitCollection {
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        return [super traitCollection];
    } else {
        return [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];
    }
}

当然欢迎任何关于更好的方法的建议。

这里是 Swift 中的相同答案,但还修复了垂直尺寸 class 在横向 phone 上错误的问题:

override var traitCollection: UITraitCollection {
    if UI_USER_INTERFACE_IDIOM() == .pad {
            return super.traitCollection
    } else {
        let horizontal = UITraitCollection(horizontalSizeClass: .compact)
        let vertical = UITraitCollection(verticalSizeClass: super.traitCollection.verticalSizeClass)
        return UITraitCollection.init(traitsFrom: [horizontal, vertical])
    }
}

我遇到了一些问题,UINavigationControllers 无法通过上面的代码正确显示。这是对我有用的方法 (Swift 5):

1) 创建一个包含 UIContainerView 的 UIViewController

2) 在那个容器中嵌入你的 UISplitViewController

3) 添加以下代码:

class SplitViewContainerViewController: UIViewController {
    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        if UI_USER_INTERFACE_IDIOM() != .pad {
            performOverrideTraitCollection()
        }
    }

    private func performOverrideTraitCollection() {
        for childVC in self.children {
            setOverrideTraitCollection(UITraitCollection(horizontalSizeClass: .compact), forChild: childVC)
        }
    }
}

4) 设置包含容器视图的视图控制器为SplitViewContainerViewController

更新 iOS 13

上面的代码不再适用于 iOS 13. 在 SplitViewContainerViewController class 上改用以下代码:

override func overrideTraitCollection(forChild childViewController: UIViewController) -> UITraitCollection? {
    if UIDevice.current.userInterfaceIdiom != .pad {
        return UITraitCollection(horizontalSizeClass: .compact)
    } else {
        return super.traitCollection
    }
}