【问题标题】:How can I change layout constraints depending on portrait/landscape programatically? [duplicate]如何以编程方式根据纵向/横向更改布局约束? [复制]
【发布时间】:2018-09-24 16:22:56
【问题描述】:

我以编程方式构建所有对象和标签,并有一个名为 setupLayout() 的函数,如下所示:

 private func setupLayout() {

//The Image that presents the Logo of the chosen cryptocurrency.
    view.addSubview(cryptoIconImage)
    cryptoIconImage.translatesAutoresizingMaskIntoConstraints = false
    cryptoIconImage.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    cryptoIconImage.topAnchor.constraint(equalTo: view.topAnchor, constant: 50).isActive = true
    cryptoIconImage.widthAnchor.constraint(equalToConstant: 60).isActive = true
    cryptoIconImage.heightAnchor.constraint(equalToConstant: 60).isActive = true


//The Label that presents the name of the chosen cryptocurrency.
    view.addSubview(cryptoLabel)
    cryptoLabel.translatesAutoresizingMaskIntoConstraints = false
    cryptoLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    cryptoLabel.topAnchor.constraint(equalTo: cryptoIconImage.bottomAnchor, constant: 10).isActive = true
    cryptoLabel.font = customFont?.withSize(32)
}

这样可以保持布局美观且居中,适用于肖像,也适用于横向。问题是在横向时,我不希望元素居中,我想将一些元素移到屏幕的左侧,一些移到右侧(我没有在设置中显示所有项目)任何其他答案对这个问题似乎都使用故事板,我发现这种方法可以使用:

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {

    let orient = UIApplication.shared.statusBarOrientation
    print(orient)

    switch orient {
    case .portrait:
        print("Portrait")
        break
    // Do something
    default:
        print("LandScape")
        // Do something else
        self.landscapeLayout()
        break
    }
}

但我不确定我应该如何更改删除和添加新约束,以便在来回时顺利运行。我想过有一个横向布局函数(),例如:

    private func landscapeLayout() {
    view.addSubview(cryptoIconImage)
    cryptoIconImage.translatesAutoresizingMaskIntoConstraints = false
//Removing centerXAnchor
    cryptoIconImage.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = false
    cryptoIconImage.topAnchor.constraint(equalTo: view.topAnchor, constant: 50).isActive = true
    cryptoIconImage.widthAnchor.constraint(equalToConstant: 60).isActive = true
    cryptoIconImage.heightAnchor.constraint(equalToConstant: 60).isActive = true
//Putting it to the left side
    cryptoIconImage.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 30).isActive = true

}

但这给我带来了拉伸等问题,并且在添加新标签内容时摆脱了标签内容。我应该如何在纵向和横向之间设置 2 个单独的布局?

【问题讨论】:

    标签: ios swift autolayout


    【解决方案1】:

    你可以这样做:

    声明变量来保存约束。

    var cryptoIconImageCenterXWhenPortrait : NSLayoutConstraint?
    var cryptoIconImageCenterXWhenLandscape : NSLayoutConstraint?
    

    定义两个约束

    cryptoIconImageCenterXWhenPortrait = cryptoIconImage.centerX.constraint(equalTo: window.centerX)
    cryptoIconImageCenterXWhenLandscape = cryptoIconImage.centerX.constraint(equalTo: window.centerX, constant: -20)
    

    相应地激活它们

    If Landscape {
       cryptoIconImageCenterXWhenPortrait.isActive = false
       cryptoIconImageCenterXWhenLandscape.isActive = true
    } else If Portrait {
       cryptoIconImageCenterXWhenPortrait.isActive = true
       cryptoIconImageCenterXWhenLandscape.isActive = false
    }
    

    【讨论】:

    • 您还需要设置 translatesAutoresizingMaskIntoConstraints = false 一次。
    • 所以我在 setupLayout 中定义了所有这些,并且对于每个约束,即我将需要 CenterXWhenPortrait、LeftAnchorWhenPortrait 等,然后只在我的横向/纵向开关中激活它们,这应该在加载时自动激活? (如有混淆,请见谅)
    • 那么在这种情况下,确定屏幕加载时的屏幕方向是有意义的(loadView/viewWillAppear),然后找到存储它的方法。您可以在设置初始约束时引用该变量。希望我说得通。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 2017-11-15
    • 1970-01-01
    相关资源
    最近更新 更多