如何解决滑块导致初始化的约束被恢复
当我使用滑块时,它会恢复到原来的位置。我不知道增加函数中发生了什么导致这样做。我想将初始化约束保留在我不希望它们删除的代码中。我只希望当用户更改对象滑块的值时,不要恢复到原始位置。您可以在 gif 中看到发生了什么。
import UIKit
class ViewController: UIViewController {
var slizer = UiSlider()
var oldCons = [NSLayoutConstraint]()
var viewDrag = UIImageView()
var panGesture = UIPanGestureRecognizer()
var widthConstraints: NSLayoutConstraint?
var tim: CGFloat = 50.0
var slidermultiplier: CGFloat = 0.6
override func viewDidLoad() {
super.viewDidLoad()
widthConstraints = viewDrag.widthAnchor.constraint(equalTo: view.widthAnchor,multiplier: slidermultiplier)
[viewDrag,slizer].forEach{
$0.translatesAutoresizingMaskIntoConstraints = false
view.addSubview($0)
}
NSLayoutConstraint.activate([
slizer.bottomAnchor.constraint(equalTo: view.bottomAnchor),slizer.leadingAnchor.constraint(equalTo: view.leadingAnchor),slizer.heightAnchor.constraint(equalTo: view.heightAnchor,multiplier: 0.2),slizer.widthAnchor.constraint(equalTo: view.widthAnchor,multiplier: 1),])
slizer.addTarget(self,action: #selector(increase),for: .valueChanged)
viewDrag.backgroundColor = .orange
viewDrag.frame = CGRect(x: view.center.x-view.frame.width * 0.05,y: view.center.y-view.frame.height * 0.05,width: view.frame.width * 0.1,height: view.frame.height * 0.1)
panGesture = UIPanGestureRecognizer(target: self,action: #selector(ViewController.draggedView(_:)))
viewDrag.isUserInteractionEnabled = true
viewDrag.addGestureRecognizer(panGesture)
oldCons = [
viewDrag.centerYAnchor.constraint(equalTo: view.centerYAnchor),viewDrag.leadingAnchor.constraint(equalTo: self.view.leadingAnchor,constant: tim),viewDrag.heightAnchor.constraint(equalTo: view.heightAnchor,multiplier: 0.3),widthConstraints!,]
NSLayoutConstraint.activate(oldCons)
}
@objc func sliderr() {
NSLayoutConstraint.deactivate(oldCons)
oldCons = [
viewDrag.centerYAnchor.constraint(equalTo: view.centerYAnchor),viewDrag.trailingAnchor.constraint(equalTo: self.view.trailingAnchor,constant: -tim),]
NSLayoutConstraint.activate(oldCons)
}
@objc func draggedView(_ sender: UIPanGestureRecognizer) {
self.view.bringSubview(toFront: viewDrag)
let translation = sender.translation(in: self.view)
viewDrag.center = CGPoint(x: viewDrag.center.x + translation.x,y: viewDrag.center.y + translation.y)
sender.setTranslation(CGPoint.zero,in: self.view)
}
@objc func increase() {
slidermultiplier = CGFloat(slizer.value)
widthConstraints?.isActive = false
widthConstraints = viewDrag.widthAnchor.constraint(equalTo: view.widthAnchor,multiplier: slidermultiplier)
widthConstraints?.isActive = true
}
}
解决方法
视图“恢复”的原因是因为你给了 viewDrag 自动布局约束......但是在你的 draggedView 函数中,你明确地设置了它的框架(使用 viewDrag.center = CGPoint(...)) .
这不会改变它的约束,一旦你做其他事情来导致它更新,UIKit 会根据它的约束重新定位/重新调整它的大小。
不是设置 .center
的 viewDrag
属性,而是为 Lead 和 CenterY(定位)创建变量约束,并更新它们的 .constant
值以移动视图。
看看这个 - 里面有很多评论来帮助说明问题:
class SlideViewController: UIViewController {
var slizer = UISlider()
var viewDrag = UIImageView()
var panGesture = UIPanGestureRecognizer()
// Width,Leading and CenterY constraints for viewDrag
var widthConstraints: NSLayoutConstraint!
var viewDragLeadingConstraint: NSLayoutConstraint!
var viewDragCenterYConstraint: NSLayoutConstraint!
var tim: CGFloat = 50.0
var slidermultiplier: CGFloat = 0.6
override func viewDidLoad() {
super.viewDidLoad()
[viewDrag,slizer].forEach{
$0.translatesAutoresizingMaskIntoConstraints = false
view.addSubview($0)
}
NSLayoutConstraint.activate([
slizer.bottomAnchor.constraint(equalTo: view.bottomAnchor),slizer.leadingAnchor.constraint(equalTo: view.leadingAnchor),slizer.heightAnchor.constraint(equalTo: view.heightAnchor,multiplier: 0.2),slizer.widthAnchor.constraint(equalTo: view.widthAnchor,multiplier: 1),])
slizer.addTarget(self,action: #selector(increase),for: .valueChanged)
viewDrag.backgroundColor = .orange
// no point setting a frame,since
// viewDrag has .translatesAutoresizingMaskIntoConstraints = false
//viewDrag.frame = CGRect(x: view.center.x-view.frame.width * 0.05,y: view.center.y-view.frame.height * 0.05,width: view.frame.width * 0.1,height: view.frame.height * 0.1)
// start with viewDrag
// width = "slidermultiplier" percent of view width
widthConstraints = viewDrag.widthAnchor.constraint(equalTo: view.widthAnchor,multiplier: slidermultiplier)
// Leading = "tim" pts from view leading
viewDragLeadingConstraint = viewDrag.leadingAnchor.constraint(equalTo: self.view.leadingAnchor,constant: tim)
// centered vertically
viewDragCenterYConstraint = viewDrag.centerYAnchor.constraint(equalTo: view.centerYAnchor)
NSLayoutConstraint.activate([
// viewDrag height will never change,so we can set it here
viewDrag.heightAnchor.constraint(equalTo: view.heightAnchor,multiplier: 0.3),// activate the 3 "modifiable" constraints
widthConstraints,viewDragLeadingConstraint,viewDragCenterYConstraint,])
panGesture = UIPanGestureRecognizer(target: self,action: #selector(draggedView(_:)))
viewDrag.isUserInteractionEnabled = true
viewDrag.addGestureRecognizer(panGesture)
// start the slider at the same percentage we've used
// for viewDrag's initial width
slizer.value = Float(slidermultiplier)
}
@objc func draggedView(_ sender: UIPanGestureRecognizer) {
// old swift syntax
//self.view.bringSubview(toFront: viewDrag)
self.view.bringSubviewToFront(viewDrag)
let translation = sender.translation(in: self.view)
viewDragLeadingConstraint.constant += translation.x
viewDragCenterYConstraint.constant += translation.y
// don't do this
//viewDrag.center = CGPoint(x: viewDrag.center.x + translation.x,y: viewDrag.center.y + translation.y)
sender.setTranslation(CGPoint.zero,in: self.view)
}
@objc func increase() {
// get the new value of the slider
slidermultiplier = CGFloat(slizer.value)
// deactivate widthConstraints
widthConstraints.isActive = false
// create new widthConstraints with slider value as a multiplier
widthConstraints = viewDrag.widthAnchor.constraint(equalTo: view.widthAnchor,multiplier: slidermultiplier)
// activate the new widthConstraints
widthConstraints.isActive = true
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。