我正在一个名为“ separatorView”的视图上创建手势(照片中为中间的黑色视图)。
我使用约束方法和优先级来做到这一点:
-centerConstraint =这是使视图在X方向水平居中的约束,优先级= 1000
-rightConstant =此约束将视图以0 pt的优先级链接到右屏幕的边缘,优先级= 999
-GaucheConstant =此约束将视图在零点链接到左屏幕的边缘,优先级= 998
当我将此视图拖动到左侧时,动画将继续拖动。
问题是动画结束后,我想恢复视图并将其拖动到左侧,现金应用中心的约束为零!
我找不到使其通用的解决方案,并且可以将视图向右或向左滑动
我知道问题出在我禁用约束的事实
这是我的代码:
@IBOutlet weak var sep: UIView!
@IBOutlet weak var constantGauche: NSLayoutConstraint!
@IBOutlet weak var constantDroite: NSLayoutConstraint!
@IBOutlet weak var centerConstraint: NSLayoutConstraint!
var startingConstant: CGFloat = 0.0
var panGesture: UIPanGestureRecognizer?
override func viewDidLoad() {
super.viewDidLoad()
panGesture = UIPanGestureRecognizer(target: self, action: #selector(detectPan(recognizer:)))
panGesture?.delaysTouchesBegan = false
panGesture?.delaysTouchesEnded = false
sep.addGestureRecognizer(panGesture!)
}
@objc func detectPan(recognizer: UIPanGestureRecognizer) {
let translation = recognizer.translation(in: self.view)
switch recognizer.state {
case .began:
self.startingConstant = self.centerConstraint.constant
case .changed:
self.centerConstraint.constant = self.startingConstant + translation.x
case .ended:
if translation.x > 0 {
centerConstraint.isActive = false
constantGauche.isActive = false
constantDroite.isActive = true
UIView.animate(withDuration: 0.5) {
self.view.layoutIfNeeded()
}
}else{
centerConstraint.isActive = false
constantGauche.isActive = true
constantDroite.isActive = false
UIView.animate(withDuration: 0.5) {
self.view.layoutIfNeeded()
}
}
default:
break
}
}
答案 0 :(得分:3)
是的,当您禁用中心约束时,iOS将从视图约束中删除它并释放它,因为不再有对其的强引用。 @IBOutlet
是一个weak
引用,只要所有强引用都消失,它就会设置为nil
。因此,下次访问中心约束时,它会崩溃,因为它是nil
,并且centerConstraint
是用!
隐式解包的。。
而不是禁用约束,而是修改其优先级:
999
作为初始值。如果尝试在代码中修改所需约束的优先级,则会出现错误。priority
的左侧和中央约束将导致sep
向右移动。到达该位置后,您可以为中心约束计算新的constant
,然后将其优先级重新设置为初始值。priority
的右侧和中央约束将导致sep
向左移动。到达该位置后,您可以为中心约束计算新的constant
,然后将其优先级重新设置为初始值。@objc func detectPan(recognizer: UIPanGestureRecognizer) {
let translation = recognizer.translation(in: self.view)
switch recognizer.state {
case .began:
self.startingConstant = self.centerConstraint.constant
case .changed:
self.centerConstraint.constant = self.startingConstant + translation.x
case .ended:
if translation.x > 0 {
centerConstraint.priority = UILayoutPriority(rawValue: 750)
constantGauche.priority = UILayoutPriority(rawValue: 750)
} else {
centerConstraint.priority = UILayoutPriority(rawValue: 750)
constantDroite.priority = UILayoutPriority(rawValue: 750)
}
UIView.animate(withDuration: 0.5) {
self.view.layoutIfNeeded()
}
print(sep.center.x - view.center.x)
centerConstraint.constant = sep.center.x - view.center.x
centerConstraint.priority = UILayoutPriority(rawValue: 999)
constantGauche.priority = UILayoutPriority(rawValue: 998)
constantDroite.priority = UILayoutPriority(rawValue: 998)
default:
break
}
}
以下是在模拟器中运行的更改: