如何更改已经具有高度锚的 UIView 的高度?

Posted

技术标签:

【中文标题】如何更改已经具有高度锚的 UIView 的高度?【英文标题】:How can I change height of UIView that already has height anchor? 【发布时间】:2017-07-17 12:43:05 【问题描述】:

如果我有这个用于子视图控制器:

autoCompleteViewController.view.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            autoCompleteViewController.view.topAnchor.constraint(equalTo: view.topAnchor, constant: 0),
            autoCompleteViewController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0),
            autoCompleteViewController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0),
            autoCompleteViewController.view.bottomAnchor.constraint(equalTo: googleMapViewController.view.topAnchor, constant: 0),
            autoCompleteViewController.view.heightAnchor.constraint(equalToConstant: 44.0)
        ])

如何更改其高度并更新heightAnchor?我试过这个:

autoCompleteViewController
            .view
            .heightAnchor
            .constraint(equalToConstant: initialHeightAutoCompleteViewController + CGFloat(numberOfSuggestions * 45))
            .isActive = true

但没有运气。我还尝试添加layoutIfNeeded() 和其他一些类似的方法,但没有奏效。如何使用锚点更新视图高度?

【问题讨论】:

我从来没有以编程方式做到这一点,但你能不将高度锚作为变量引用吗?这样你就可以做 heightVariable.constant += randomIntValue,然后调用 UIView.animate(withDuration: 1.0 self.view.layoutIfNeeded) 错误尝试。每当您通过代码更新约束时,首先您必须删除组件上以前的约束,然后您必须再次提供约束。 @dahiya_boy - 错误答案! :-) 当然,您可以 删除先前的约束,但这只是至少三个选项中的一个。另外两个 - 可能还有更多 - 是 (1) deactivate 所述约束,然后添加一个替换它的约束和 (2) update 所述约束。 【参考方案1】:

除了@Mukesh 答案只是更新约束:

var heightAnchor:NSLayoutConstraint!

override func viewDidLoad() 
    super.viewDidLoad()
    heightAnchor = autoCompleteViewController.view.heightAnchor.constraint(equalToConstant:44.0)
    heightAnchor.isActive = true


func changeMyHeight(numberOfSuggestions: Int) 
    heightAnchor.constant = 44.0 + CGFloat(numberOfSuggestions * 45)

注意事项:

您不能在类级别完全声明此变量,因为 autoCompleteViewController.view 尚未实例化。 您不能同时设置约束设置isActive = true。我总是遇到构建错误。

【讨论】:

我已经实现了类似于您的解决方案。 很好的答案,但是快速添加,我认为您不需要再次激活或停用约束。保留对约束的引用,只需编辑常量值。视图将被修改。 @Yoku,根据我的经验,您有两个选项之一 - 激活/停用或添加/删除。甚至 Apple 的文档也设置为 isActive = true。也许您正在考虑通过 Interface Builder 创建的约束? (这些默认情况下被激活。OP暗示(a)约束是在代码中创建的并且(b)已经有一个“高度锚”,这表明使用VFL - 这可能涉及添加/删除 - 不是一个好的路线去。developer.apple.com/library/archive/documentation/… @dfd,我只评论了程序设置。我只是想强调isActivate = true 只需要在设置时完成,因为它与所提问题的标题有关。稍后只是为了更改高度,请正确调用您在上面创建的函数。【参考方案2】:

如果您不想保留对高度锚点的引用,这里有一个替代方案:

myVC.view.constraints.forEach  (constraint) in
     if constraint.firstAttribute == .height
     
         constraint.constant = newHeight
     
 

【讨论】:

【参考方案3】:

首先你禁用了前一个约束并激活另一个

例如

let heightAnchor_one = autoCompleteViewController.view.heightAnchor.constraint(equalToConstant: x)

let heightAnchor_two = autoCompleteViewController.view.heightAnchor.constraint(equalToConstant: y)

heightAnchor_one.isActive = true

heightAnchor_two.isActive = false

然后,您需要激活该约束并禁用另一个约束。

【讨论】:

【参考方案4】:

你可以这样做:

class ViewController: UIViewController 

    var constantValue: CGFloat = 44

    let childView: UIView = 
        let view = UIView()
        view.backgroundColor = .red
        return view
    ()

    override func viewDidLoad() 
        super.viewDidLoad()

        view.addSubview(childView)

        childView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            childView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0),
            childView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0),
            childView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0),
            childView.heightAnchor.constraint(equalToConstant: constantValue)
            ])

    

    @IBAction func changeHeight(_ sender: UIButton) 

        constantValue = 100

        UIView.animate(withDuration: 0.5, animations: 

            if let constraint = (self.childView.constraints.filter$0.firstAttribute == .height.first) 

                constraint.constant = self.constantValue
            

            self.view.layoutIfNeeded()
        )
    


【讨论】:

【参考方案5】:

我已经通过这样实现它来修复它:

autoCompleteViewControllerHeight = NSLayoutConstraint( item: autoCompleteViewController.view, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1.0, constant: 44.0) guard let autoCompleteViewControllerHeight = autoCompleteViewControllerHeight else return autoCompleteViewControllerHeight.isActive = true

然后我添加了应该更改的位置:

let newHeight = calculateNewHeight() heightConstraintAutoCompleteViewController.constant = newHeight

它就像一个魅力。

【讨论】:

以上是关于如何更改已经具有高度锚的 UIView 的高度?的主要内容,如果未能解决你的问题,请参考以下文章

更改 UITableViewCell 内 UIView 的高度(故事板)

更改 UITableViewCell 内的 UIView 高度

如何在tableview标题中更改uiview的高度

如何在 Swift 中使用 SnapKit 使 UIView 具有相等的宽度和高度?

使用自动布局约束以编程方式创建四个具有相同高度和宽度的 UIView

从 UIText 字段的用户输入更改 UIView 框架的高度和宽度