【问题标题】:Different size classes for iPad portrait and landscape modes with containerviews带有容器视图的 iPad 纵向和横向模式的不同尺寸等级
【发布时间】:2016-06-25 05:35:27
【问题描述】:

我找到了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;
}

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

当我不分配 rootviewcontroller 时,它看起来像这样

虽然它在纵向模式下应该是这样的

有谁知道这里可能出了什么问题?为什么它没有像期望的那样改变尺寸等级。

编辑 就像@Muhammad Yawar Ali 在这里问的一样,是我设置的所有尺寸等级位置的屏幕截图。我对任何约束都没有警告或错误,因此这些屏幕截图包含更新后的视图。

我希望这能显示所需的一切。

编辑: 由于某种原因,我无法放入所有屏幕截图

【问题讨论】:

    标签: ios swift ipad storyboard size-classes


    【解决方案1】:

    viewWillTransitionToSize 上,您还需要调用 super,将事件传递给下一个响应者(您的 rootviewcontroller)...

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

    【讨论】:

    • 我申请了 super 但不幸的是它没有改变任何东西
    【解决方案2】:

    意识到这已经超过两年了,但是......

    我刚刚遇到了我认为类似的问题。您可能忘记的是,'overrideTraitCollectionForChildViewController' 仅覆盖视图 children,因此此方法不会对容器执行任何操作,因为它们位于根目录中。

    我解决了这个问题,将我的两个容器放在 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];
    }
    

    如果您在纵向和横向之间有任何不同的限制,您也需要在代码中进行调整。

    我想你也可以通过将带有容器的视图控制器嵌入另一个视图控制器来解决这个问题。

    【讨论】:

      【解决方案3】:

      我已经从存储库中克隆了您的代码:https://github.com/MaikoHermans/sizeClasses.git 编辑后的代码将以下代码放入您的控制器中,它将正常工作并且不会影响您在 iPad 中的设计。 导入 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 您能否确认您在哪些维度上应用了约束?要使约束在所有设备上起作用,您必须在 wAny*hAny 基值维度中应用它们。为了在多个设备上进行设计,您必须在多个维度上添加约束。
      • 看看我刚刚做的编辑。我已经更改了我尝试放入所有屏幕截图的所有尺寸类,但是由于某种原因,我无法发布比目前更多的屏幕截图
      • @NoSixties 选择 wRegularhRegular 尺寸并设计 ipad 视图请记住,如果您在 wAnyhAny 尺寸上应用约束,它们将影响所有分辨率和设备,但在 wRegular*hRegular 约束只会影响 ipad 和横向视图。
      • @NoSixties 你可以将你的代码添加到 git 并分享我可以查看它的解决方案吗?
      猜你喜欢
      • 2015-11-11
      • 2015-04-01
      • 1970-01-01
      • 2015-10-14
      • 1970-01-01
      • 2011-11-13
      • 1970-01-01
      • 2015-09-04
      • 1970-01-01
      相关资源
      最近更新 更多