通过代码使用约束移动 UI 元素

问题描述

我正在尝试使用约束制作一个简单的动画。 按下按钮时,会发生以下情况:

First step

Second step

我为高度和布尔值创建了两个变量

    var isCollectionopen = false
    var collectionHeightConstraint = NSLayoutConstraint()

通过代码为整个用户界面设置限制,并在同一个地方将集合的高度设置为一个变量

// ...
        btcView.collectionView.heightAnchor.constraint(equalToConstant: collectionHeightConstraint.constant),// ...

我正在尝试更改按下按钮时的限制。但什么也没有发生。我的问题是什么?


    func example() {
        collectionHeightConstraint.constant = isCollectionopen ? (view.frame.width / 4) : 0
        isCollectionopen = !isCollectionopen
    }

解决方法

这很简单。您似乎正在尝试使一个约束等于另一个约束,然后只是更改另一个常量。

这个

btcView.collectionView.heightAnchor.constraint(equalToConstant: collectionHeightConstraint.constant)

只是读取 collectionHeightConstraint 的当前值。它不会使约束神奇地保持与 collectionHeightConstraint 相同的值。

相反:

var collectionHeightConstraint: NSLayoutConstraint?

并存储对创建的约束的引用:

collectionHeightConstraint = btcView.collectionView.heightAnchor.constraint(equalToConstant: 0)

然后简单地改变它:

collectionHeightConstraint.constant = isCollectionOpen ? (view.frame.width / 4) : 0

然而,这不是最好的解决方案。我个人会创建两个具有不同优先级的约束:

let hiddenConstraint = btcView.collectionView.heightAnchor.constraint(equalToConstant: 0)
hiddenConstraint.priority = UILayoutPriority.required - 1
self.visibleConstraint = btcView.collectionView.heightAnchor.constraint(equalTo: view.widthAnchor,multiplier: 1 / 4)

然后只需切换 visibleConstraint.isActive = false 隐藏视图和 visibleConstraint.isActive = true 隐藏视图。

,

借助答案@Sulthan

我做了以下事情:

  1. 创建了两个变量
    var isCollectionOpen = false
    var visibleConstraint: NSLayoutConstraint?
  1. 在约束存储中
    let hiddenConstraint = btcView.collectionView.heightAnchor.constraint(equalToConstant: 0)
    hiddenConstraint.priority = UILayoutPriority.required - 1
    visibleConstraint = btcView.collectionView.heightAnchor.constraint(equalTo: view.widthAnchor,multiplier: 1 / 4)

// ...
    btcView.collectionView.heightAnchor.constraint(equalToConstant: hiddenConstraint.constant),// ...
  1. 我在哪里获取数据到集合中
    if !isCollectionOpen {
        visibleConstraint?.isActive = true
        isCollectionOpen = true
    } else {
        visibleConstraint?.isActive = false
        isCollectionOpen = false
        return // Don't download data again
    }