iPad纵向和横向模式下使用Containerviews的不同尺寸类别

4

我发现了this个问题,并尝试实现给出的解决方案。然而,我遇到了一个问题。

我的初始视图控制器有两个容器视图,它们都有自己的视图控制器。我创建了一个根视图控制器,将其分配给初始视图控制器。这个类中的代码看起来像这样。

class RootViewController: UIViewController {

var willTransitionToPortrait: Bool!
var traitCollection_CompactRegular: UITraitCollection!
var traitCollection_AnyAny: UITraitCollection!

override func viewDidLoad() {
    super.viewDidLoad()
    setupReferenceSizeClasses()
    // Do any additional setup after loading the view.
}

override func viewWillAppear(animated: Bool) {
    willTransitionToPortrait = self.view.frame.size.height > self.view.frame.size.width
}

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    willTransitionToPortrait = size.height > size.width
}

func setupReferenceSizeClasses(){
    let traitCollection_hCompact = UITraitCollection(horizontalSizeClass: .Compact)
    let traitCollection_vRegular = UITraitCollection(verticalSizeClass: .Regular)
    traitCollection_CompactRegular = UITraitCollection(traitsFromCollections: [traitCollection_hCompact, traitCollection_vRegular])
    
    let traitCollection_hAny = UITraitCollection(horizontalSizeClass: .Unspecified)
    let traitCollection_vAny = UITraitCollection(verticalSizeClass: .Unspecified)
    traitCollection_AnyAny = UITraitCollection(traitsFromCollections: [traitCollection_hAny, traitCollection_vAny])
}

override func overrideTraitCollectionForChildViewController(childViewController: UIViewController) -> UITraitCollection? {
    let traitCollectionForOverride = ((willTransitionToPortrait) != nil) ? traitCollection_CompactRegular : traitCollection_AnyAny
    
    return traitCollectionForOverride;
}

然而,当我运行它时,尺寸类不会像它应该的那样响应。其中一个容器视图控制器在横向和纵向模式下都会开始表现奇怪,如下所示。

landscape mode portrait mode

当我不指定根视图控制器时,它会看起来像这样landscape modeportrait mode。而在纵向模式下应该是这样的portrait mode how it should look。有人知道可能出了什么问题吗?为什么它不能按照预期更改大小类别。
编辑:如@Muhammad Yawar Ali所问,这里是我设置的所有大小类别位置的屏幕截图。我没有任何约束的警告或错误,因此这些屏幕截图包含更新的视图。

enter image description here enter image description here

我希望这展示了所有需要的内容。
编辑: 由于某些原因,我无法放入所有的截图。
3个回答

2
viewWillTransitionToSize中,您需要调用super,将事件传递给下一个响应者(即您的根视图控制器)...
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
    willTransitionToPortrait = size.height > size.width
}

我使用了super,但不幸的是它没有改变任何东西。 - NoSixties

0

意译:我知道这篇文章已经两年了,但是...

我刚刚遇到了一个类似的问题。你可能忘记了 'overrideTraitCollectionForChildViewController' 只会覆盖视图子级,所以这个方法对容器不起作用,因为它们位于根目录。

我通过在 Interface Builder 中将我的两个容器放入 UIStackView 中,并在代码中创建了该堆栈的属性,然后根据方向更新轴来解决了这个问题。例如,在 Objective-C 中:

@property (weak, nonatomic) IBOutlet UIStackView *rootStack;

// ...

- (UITraitCollection *)overrideTraitCollectionForChildViewController:(UIViewController *)childViewController
{
    if (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPad) {
        return [super overrideTraitCollectionForChildViewController:childViewController];
    }

    if (CGRectGetWidth(self.view.bounds) < CGRectGetHeight(self.view.bounds)) {
        self.rootStack.axis = UILayoutConstraintAxisVertical;
        return [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];
    }
    else {
        self.rootStack.axis = UILayoutConstraintAxisHorizontal;
        return [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular];
}

如果您在纵向和横向之间有任何不同的限制,您也需要在代码中进行调整。
我想您也可以通过将带有容器的视图控制器嵌入另一个视图控制器来解决这个问题。

-1

我已经从代码库克隆了你的代码: https://github.com/MaikoHermans/sizeClasses.git 并且编辑了代码,将下面的代码放入你的控制器中,它将正常工作,并不会影响你在iPad上的设计。 import UIKit

class RootViewController: UIViewController {

   override func viewDidLoad() {
      super.viewDidLoad()
      // Do any additional setup after loading the view.
   }

   override func overrideTraitCollectionForChildViewController(childViewController: UIViewController) -> UITraitCollection? {
      if view.bounds.width < view.bounds.height {
         return UITraitCollection(horizontalSizeClass: .Unspecified)
      } else {
         return UITraitCollection(horizontalSizeClass: .Regular)
      }
   }
}

你可以尝试这段代码,但我认为存在一个问题,即它不能正确地更新iPad的特性,视图布局仍然相同,但看起来不错。我已经尝试了多种方法,但还没有成功,将会更新我的答案。


我已经在所有需要的方向上应用了限制条件。当我在任何iPhone设备上运行它时,它们的确像应该的那样工作。但是在任何iPad设备上却无法正常工作。 - NoSixties
@NoSixties 你能确认你在哪个维度上应用了约束吗?为了让约束适用于所有设备,必须将它们应用于wAny*hAny基础值的尺寸中。为了使设计适用于多个设备,必须在多个维度上添加约束。 - Muhammad Ali
看看我刚刚做的修改。我已经更改了所有尺寸类别,我试图把所有的截图放在里面,但由于某种原因,我无法发布比它当前拥有的更多的截图。 - NoSixties
@NoSixties 选择wRegularhRegular尺寸并设计iPad视图。请记住,如果您在wAnyhAny尺寸上应用约束,则它们将影响所有分辨率和设备,但在wRegular*hRegular尺寸上,约束仅会影响iPad和横向视图。 - Muhammad Ali
@NoSixties,你能把你的代码上传到Git并分享吗?我可以看一下是否有解决方案。 - Muhammad Ali
这是一个使用Size Classes的示例项目。我已在iPhone 6模拟器上进行了测试。当我使用标准视图控制器时,它可以正常工作。但是当我在初始视图上使用rootviewcontroller时,它会出现问题。https://github.com/MaikoHermans/sizeClasses.git - NoSixties

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