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
}
}
}