导致初始化约束被还原的滑块
slider causing initialized constraints to be reverted
当我使用滑块时,它会恢复到原来的位置。我不知道 increase func 中发生了什么导致这样做。我想在我不想删除的代码中保留初始化约束。我只想在用户更改对象的滑块值时不恢复到原始位置。你可以在 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{
[=10=].translatesAutoresizingMaskIntoConstraints = false
view.addSubview([=10=])
}
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),
viewDrag.heightAnchor.constraint(equalTo: view.heightAnchor,multiplier: 0.3),
widthConstraints!,
]
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 就会re-position/re-size它基于它的约束。
不是设置 viewDrag
的 .center
属性,而是为 Leading 和 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{
[=10=].translatesAutoresizingMaskIntoConstraints = false
view.addSubview([=10=])
}
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
}
}
当我使用滑块时,它会恢复到原来的位置。我不知道 increase func 中发生了什么导致这样做。我想在我不想删除的代码中保留初始化约束。我只想在用户更改对象的滑块值时不恢复到原始位置。你可以在 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{
[=10=].translatesAutoresizingMaskIntoConstraints = false
view.addSubview([=10=])
}
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),
viewDrag.heightAnchor.constraint(equalTo: view.heightAnchor,multiplier: 0.3),
widthConstraints!,
]
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 就会re-position/re-size它基于它的约束。
不是设置 viewDrag
的 .center
属性,而是为 Leading 和 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{
[=10=].translatesAutoresizingMaskIntoConstraints = false
view.addSubview([=10=])
}
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
}
}