Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 更新视图约束中的变量(SnapKit)_Swift_Autolayout_Snapkit - Fatal编程技术网

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

Swift 更新视图约束中的变量(SnapKit),swift,autolayout,snapkit,Swift,Autolayout,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 =

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


  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

当父视图更改其尺寸时。视图不会更新其高度,因为约束不会再次调用。 任何更新或调用其约束的方法,除了在大规模情况下不可行的remakingConstraint。 已尝试:

View.updateConstraints()
View.setNeedsUpdateConstraints()
View.setNeedsLayout()
我需要引用每个约束,因为

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

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

是否有理由不使用父视图高度的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%上”是完全不同的问题

试试这个

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

当父视图框架发生变化时(通过点击或设备旋转),则“子视图”底部将重置为“父视图”高度的50%:


一切都很好。如果我手动调用我的约束,那么它会得到纠正。我要求任何方法,我可以更新或刷新我的约束。疯狂的尊重!写了超过3k行的约束,但没有考虑到这一点。我使用的是自上而下的前导尾随,因为我也在为以后的更改保存这些约束,但我会找到一种方法。self.View.bottomConstraint=para.bottom.equalTo(parentview.snp.bottom)。offset(-getheight).constraint现在是额外的。我有什么办法可以得到它的引用吗?因为我需要它。@divide-我想你需要解释一下为什么需要它。来计算可能从任何一边开始的第一次触碰偏移。@divide-嗯?我希望你在触摸时检查一下框架。。。我想不出哪种情况下你会对约束做任何事情。
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
        }
        
    }
    
}