更新视图约束中的变量 (SnapKit)

Updating variable in view constraint (SnapKit)

视图已使用以下约束进行初始化


  View.snp.makeConstraints { (para) in
       View.topConstraint = para.top.equalTo(parentview.snp.top).constraint
       View.LeadingConstraint = para.leading.equalTo(parentview.snp.leading).constraint
       View.TrailingConstraint = para.trailing.equalTo(parentview.snp.trailing).constraint
       View.BottomConstraint =para.bottom.equalTo(parentview.snp.bottom).offset(-getheight).constraint
        
  }

其中 getheight = parentview.frame.size.height/2 ;

当父视图更改时,其 dimensions.View 不会更新其高度,因为不会再次调用约束。 除了大规模不可行的 remakingConstraint 之外,任何更新或召回其约束的方法。 尝试过:

View.updateConstraints()
View.setNeedsUpdateConstraints()
View.setNeedsLayout()

我需要参考每个约束,因为

if View.bottomTouch {
      View.bottomConstraint.update(offset: View. BottomConstraint.layoutConstraints[0].constant + CurrentPoint - PreviousPoint)
}

首先检查getheight值是否在父视图布局改变时更新。为了重新加载现有约束,您可能需要调用父视图的 layoutIfNeeded()

您不想使用父视图高度的 50% 有什么原因吗?

    View.snp.makeConstraints { (para) in
        para.top.equalTo(parentview.snp.top)
        para.leading.equalTo(parentview.snp.leading)
        para.trailing.equalTo(parentview.snp.trailing)

        // 50% of the parent view height
        para.height.equalTo(parentview.snp.height).multipliedBy(0.5)

        // instead of this
        //para.bottom.equalTo(parentview.snp.bottom).offset(-getheight)
    }

编辑 - 评论后...

为了拖动视图而保留对约束的引用与“将子视图保持在父视图高度的 50%”是一个非常不同的问题。

试一试...

它将创建一个 cyan“parentView”和一个 blue“childView”(子视图)。 拖动 蓝色视图(平移手势)将向上/向下拖动其底部。点击任意位置(点击手势)将在 20 到 60 之间切换 parentView 框架上的插图。

当 parentView 框架发生变化时——无论是通过点击还是在设备旋转时——“childView”底部将重置为“parentView”高度的 50%:

class ViewController: UIViewController {

    let parentView = UIView()
    let childView = UIView()
    
    // childView bottom constraint
    var bc: Constraint!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        parentView.backgroundColor = .cyan
        childView.backgroundColor = .blue
        
        parentView.addSubview(childView)
        view.addSubview(parentView)
        
        parentView.snp.makeConstraints { para in
            para.top.leading.trailing.bottom.equalTo(self.view.safeAreaLayoutGuide).inset(20.0)
        }
        
        // childView's bottom constraint offset will be set in viewDidLayoutSubviews()
        childView.snp.makeConstraints { para in
            para.top.leading.trailing.equalToSuperview()
            bc = para.bottom.equalToSuperview().constraint
        }
        
        let p = UIPanGestureRecognizer(target: self, action: #selector(panHandler(_:)))
        childView.addGestureRecognizer(p)
        
        let t = UITapGestureRecognizer(target: self, action: #selector(tapHandler(_:)))
        view.addGestureRecognizer(t)
    }

    @objc func tapHandler(_ g: UITapGestureRecognizer) -> Void {
        
        // on tap, toggle parentView inset
        //  between 20 and 60
        // this will trigger viewDidLayoutSubviews(), where the childView bottom
        //  constraint will be reset to 50% of the parentView height
        var i: CGFloat = 60.0
        if parentView.frame.origin.x > 20 {
            i = 20.0
        }
        parentView.snp.updateConstraints { para in
            para.top.leading.trailing.bottom.equalTo(self.view.safeAreaLayoutGuide).inset(i)
        }
        
    }

    @objc func panHandler(_ g: UIPanGestureRecognizer) -> Void {
        
        let translation = g.translation(in: g.view)

        // update bottom constraint constant
        bc.layoutConstraints[0].constant += translation.y
        
        // reset gesture translation
        g.setTranslation(CGPoint.zero, in: self.view)

    }
    
    var parentViewHeight: CGFloat = 0.0
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        
        // reset childView's bottom constraint
        //  to 50% of its superView's height
        //  ONLY if parentView frame height has changed
        if parentView.frame.height != parentViewHeight {
            parentViewHeight = parentView.frame.height
            bc.layoutConstraints[0].constant = -parentViewHeight * 0.5
        }
        
    }
    
}