如何通过代码在方向更改时添加对 UIStackView.Axis 的更改?

Posted

技术标签:

【中文标题】如何通过代码在方向更改时添加对 UIStackView.Axis 的更改?【英文标题】:How do I by code add a change to UIStackView.Axis on orientation change? 【发布时间】:2015-09-17 12:59:06 【问题描述】:

我有几个UIStackView,我以编程方式添加,我希望他们有另一个Axis,当应用程序在说Regular Width and Any Height时。

这甚至可能,就像在界面构建器中一样?

我在 Google 上遇到的只是 willTransitionToTraitCollection,但不是我需要的。

为了更容易理解我需要什么:

for i in numberOfItems 
    let stackView = UIStackView()
    stackView.append... // add views in this new stack view

    // here is where I need help:
    stackView.axis = horizontal
    stackView.addSomething... stackView.axis = vertical if regular width and any height.

    existingStackView.append.... stackView

编辑:

我找到了另一种方法,但是当我旋转 iPhone 6+ 时,我得到了一些奇怪的行为。 Git 仓库:https://github.com/bjaskj/iosStackViewConstraints

class MyStackView: UIStackView 
    override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) 
        super.traitCollectionDidChange(previousTraitCollection)

        if traitCollection.horizontalSizeClass == UIUserInterfaceSizeClass.Regular 
            axis = UILayoutConstraintAxis.Horizontal
         else 
            axis = UILayoutConstraintAxis.Vertical
        
    

视图控制器:

@IBOutlet weak var mainStackView: UIStackView!

override func viewDidLoad() 
    super.viewDidLoad()
    addElement("Name", description: "Saint Petersburg")
    addElement("Native name", description: "Санкт-Петербург")
    addElement("Country", description: "Russia")
    addElement("Federal district", description: "Northwestern")
    addElement("Economic region", description: "Northwestern")
    addElement("Established", description: "May 27, 1703")


func addElement(title:String, description:String) 

    let labelTitle = UILabel()
    labelTitle.backgroundColor = UIColor.redColor()
    labelTitle.font = UIFont.preferredFontForTextStyle(UIFontTextStyleHeadline)
    labelTitle.text = title
    labelTitle.textColor = UIColor.whiteColor()

    let labelDescription = UILabel()
    labelDescription.backgroundColor = UIColor.blueColor()
    labelDescription.font = UIFont.preferredFontForTextStyle(UIFontTextStyleBody)
    labelDescription.text = description
    labelDescription.textColor = UIColor.whiteColor()

    let stackHolder = MyStackView()
    stackHolder.axis = .Vertical
    stackHolder.distribution = .FillEqually

    stackHolder.addArrangedSubview(labelTitle)
    stackHolder.addArrangedSubview(labelDescription)
    stackHolder.spacing = 8

    mainStackView.addArrangedSubview(stackHolder)

当我旋转iPhone 6+ 时会发生什么:

但是如果我以旋转位置启动应用程序,我期望并得到什么:

【问题讨论】:

您是否尝试更改轴?顺便提一句。 IB 中所有可能的事情都可以在代码中完成。 watchOS 开发除外。 更改工作的轴是的,但是我正在寻找的是当我创建这些 UIStackViews 时,他们已将其添加到其中,而不是我必须依靠视图控制器事件来得到通知,然后循环通过我的堆栈来适应。 【参考方案1】:

更新:

好的,看来您有两个问题:

1)当我将stackviews添加到场景中时,如何根据大小类添加适当的stackview.axis:

for i in numberOFItems 
    let stackView = UIStackView()

    if view.traitCollection.verticalSizeClass == .Unspecified && view.traitCollection.horizontalSizeClass == .Regular 
        stackView.axis = .Vertical
     else 
        stackView.axis = .Horizonal
    

    stackView.addArrangedSubview(arrayOfViews[i])

2)当手机方向改变时,如何使stackview从水平轴变为垂直轴:

您将需要一个已初始化的堆栈视图数组。然后,您需要在委托方法中逐步浏览堆栈视图并更改它们的方向。

override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) 
    var axis

    if view.traitCollection.verticalSizeClass == .Compact 
        axis = UILayoutConstraintAxis.Horizontal
     else 
        axis = UILayoutConstraintAxis.Vertical
    

    for stackView in stackViewArray 
        stackView.axis = axis
    

视图有一个 traitCollection,它包括verticalSizeClass 和horizo​​ntalSizeClass。它们的值可以是 .Compact、.Regular 和 .Unspecified。

traitCollectionDidChange 方法应该告诉您何时修改尺寸类(即当手机转动时)。

如果这仍然不能回答您的问题,请尝试重写您的问题,以便更容易理解

另外,据我所知,没有办法设置这些属性一次并完成它,你必须照顾这两种情况。

【讨论】:

我不确定你是否理解正确,是否可以在我的 for 循环中执行此操作,而不是在 UIViewController/UIView 上执行此操作,然后在我的子视图上执行 for 循环?或者创建一个自定义类来继承 UIStackView 并针对我可能需要的每种情况覆盖它。界面生成器如何做到这一点?当您将其连接到情节提要或 XIB 时,他们是否添加了一些魔术代码,通过 UIViewController 或 UIView 上的 traitCollectionDidChange 进行设置? 嗨@Bjarte,我更新了我的答案。您可以检查一些全局变量来告诉您大小类。干杯! 那么当我在“//这里是我需要帮助的地方:”下发布的代码中旋转设备时,这将如何改变轴?我想做一次添加操作。 我找到了一些其他的方法,但它几乎解决了它。它只是在 iPhone 6+ 上行为不端。 纵向有两列吗?

以上是关于如何通过代码在方向更改时添加对 UIStackView.Axis 的更改?的主要内容,如果未能解决你的问题,请参考以下文章

如何更改 iDevice (iPad/iPhone) 的方向?

iOS 6 - 如何在方向改变时运行自定义代码

设备方向更改时如何重新排列集合视图单元格

如何在屏幕方向更改时附加片段?

方向更改时不可见的片段

在 SwiftUI 中更改方向时更新 UI