Ios 如何使用平移手势识别器更改不同视图的布局约束?
我有一个功能,每次按下按钮时,都会向主视图添加一个新的Ios 如何使用平移手势识别器更改不同视图的布局约束?,ios,swift,uigesturerecognizer,Ios,Swift,Uigesturerecognizer,我有一个功能,每次按下按钮时,都会向主视图添加一个新的UIView。我希望每个视图都可以拖动。目前,我正在为每个视图添加一个平移手势识别器,从而更改每个视图的布局约束 我的问题是,我没有在移动每个视图之前正确禁用其原始约束,因此新约束和旧约束相互冲突 这是我的密码: import UIKit class ViewController5: UIViewController, UINavigationControllerDelegate, UIGestureRecognizerDelegate {
UIView
。我希望每个视图都可以拖动。目前,我正在为每个视图添加一个平移手势识别器,从而更改每个视图的布局约束
我的问题是,我没有在移动每个视图之前正确禁用其原始约束,因此新约束和旧约束相互冲突
这是我的密码:
import UIKit
class ViewController5: UIViewController, UINavigationControllerDelegate, UIGestureRecognizerDelegate {
var textPosXConstraint = NSLayoutConstraint()
var textPosYConstraint = NSLayoutConstraint()
var numberOfViews = 0
var startingConstantPosX: CGFloat = 0.0
var startingConstantPosY: CGFloat = 100.0
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "edit views"
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "add", style: .plain, target: self, action: #selector(addView))
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Clear", style: .plain, target: self, action: #selector(clearThis))
}
@objc func addView() {
let view1 = UIView()
view1.backgroundColor = UIColor.yellow
view1.frame = CGRect()
view.addSubview(view1)
view1.translatesAutoresizingMaskIntoConstraints = false
view1.widthAnchor.constraint(equalToConstant: 80).isActive = true
view1.heightAnchor.constraint(equalToConstant: 80).isActive = true
textPosXConstraint = view1.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0)
textPosXConstraint.isActive = true
textPosYConstraint = view1.centerYAnchor.constraint(equalTo: view.topAnchor, constant: 100)
textPosYConstraint.isActive = true
numberOfViews+=1
view1.tag = numberOfViews
//add pan gesture
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePan))
panGestureRecognizer.delegate = self
view1.addGestureRecognizer(panGestureRecognizer)
}
@objc func clearThis() {
for view in view.subviews {
view.removeFromSuperview()
}
numberOfViews = 0
}
@objc func handlePan(_ gestureRecognizer: UIPanGestureRecognizer) {
guard let currentView = gestureRecognizer.view else { return }
if gestureRecognizer.state == .began {
print("view being moved is: \(currentView.tag)")
startingConstantPosY = textPosYConstraint.constant
startingConstantPosX = textPosXConstraint.constant
} else if gestureRecognizer.state == .changed {
let translation = gestureRecognizer.translation(in: self.view)
let newXConstant = self.startingConstantPosX + translation.x
let newYConstant = self.startingConstantPosY + translation.y
currentView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: startingConstantPosX).isActive = false
currentView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: newXConstant).isActive = true
}
}
}
理想情况下,它将工作,以便用户可以添加任意多的视图,并移动每个视图
谢谢你的帮助 您需要保留对为视图创建的位置约束的引用,以便您可以在创建新约束之前更改其
常量
值或设置isActive=false
moveableView.horizontalConstraint?.isActive = false
moveableView.verticalConstraint?.isActive = false
moveableView.horizontalConstraint = ...
moveableView.horizontalConstraint?.isActive = true
moveableView.verticalConstraint = ...
moveableView.verticalConstraint?.isActive = true
MovableView
的UIView
子类,该子类具有NSLayoutConstraint?
横向约束和垂直约束
的属性isActive=true
之前,在创建约束时设置这些属性MovableView
时,更新水平约束
和垂直约束
的常量
属性
moveableView.horizontalConstraint?.constant = newXConstant
moveableView.verticalConstraint?.constant = newYConstant
或者,您可以在创建、分配和激活新约束之前设置水平约束?.isActive=false
和垂直约束?.isActive=false
moveableView.horizontalConstraint?.isActive = false
moveableView.verticalConstraint?.isActive = false
moveableView.horizontalConstraint = ...
moveableView.horizontalConstraint?.isActive = true
moveableView.verticalConstraint = ...
moveableView.verticalConstraint?.isActive = true
我修正了你的代码:
- 您没有提供
的实现,但约束属性似乎是MovableView
而不是成员属性。为了支持多个可移动视图,需要将它们作为成员属性static
- 您交换了
和startingConstantPosX
,这就是导致跳转的原因startingConstantPosY
如果每次调用
handlePan
时都将translation
设置回.zero
,则无需跟踪起始位置即可简化代码:
@objc func handlePan(_ gestureRecognizer: UIPanGestureRecognizer) {
guard let currentView = gestureRecognizer.view as? MovableView else { return }
if gestureRecognizer.state == .began {
print("view being moved is: \(currentView.tag)")
} else if gestureRecognizer.state == .changed {
let translation = gestureRecognizer.translation(in: self.view)
currentView.horizontalConstraint?.constant += translation.x
currentView.verticalConstraint?.constant += translation.y
gestureRecognizer.setTranslation(.zero, in: self.view)
}
}
谢谢你的回答-我实现了它,它朝着正确的方向发展,但是当我第二次尝试拖动一个视图时,它会飞出屏幕。如果你有任何想法,这就是我得到的--我也同意,跳过自动布局会更容易,我一开始是这样做的,但这些最终将是UITextView,当你输入它们时会扩展,所以我需要约束条件。再次感谢:)哇,这太棒了-非常感谢你的帮助!我真的很感激!:)