Here is an image of a simple APP I am trying to make
该应用程序具有用于中心紫色按钮的平移手势识别器,该按钮在移动时如果与四个橙色按钮中的任意一个相交,则该紫色按钮会进行动画处理并在与之交界的按钮范围内移动,否则会动画化回到初始起始位置即中心。
第一次平移紫色按钮时,按钮的框架会更新,但是如果第二次尝试,按钮的框架将保持不变(当它位于视图中心时的值)。
我猜想这是我缺少的与“自动版式”相关的内容,因为如果我取消了紫色中心按钮的约束,则每次平移时帧都会正确更新。
有人可以解释约束动画时我要记住的几点吗
这是我用于处理平移手势的代码:
@objc func handleCenterRectPan(_ pannedView: UIPanGestureRecognizer) {
let fallBackAnimation = UIViewPropertyAnimator(duration: 0.3, dampingRatio: 0.5) {
if self.button1.frame.intersects(self.centerRect.frame) {
self.centerRect.center = self.button1.center
} else if self.button2.frame.contains(self.centerRect.frame) {
self.centerRect.center = self.button2.center
} else if self.button3.frame.contains(self.centerRect.frame) {
self.centerRect.center = self.button3.center
} else if self.button4.frame.contains(self.centerRect.frame) {
self.centerRect.center = self.button4.center
} else {
// no intersection move to original position
self.centerRect.frame = OGValues.oGCenter
}
}
switch pannedView.state {
case .began:
self.centerRect.center = pannedView.location(in: self.view)
case .changed:
print("Changed")
self.centerRect.center = pannedView.location(in: self.view)
case .ended, .cancelled, .failed :
print("Ended")
fallBackAnimation.startAnimation();
//snapTheRectangle()
default:
break
}
}
最佳答案
首先,如果您的目标是平稳地移动视图,则不应施加任何限制。而且,如果您无法抗拒约束,那么必须继续更新约束而不是框架(中心),
在您的代码中,我假设您已经给了紫色按钮中心约束,然后随着用户使用平移手势拖动来更改按钮的中心。问题是给您的约束仍然处于活动状态,并且在布局需要更新时会尝试将其重新设置。
所以你可以做的是
不要给出限制,因为当用户拖动时它需要自由移动
要么
为约束创建IBoutlet,并在用户拖动时将.isActive设置为false,如果它不在其他任何按钮中,则将其设置为true,并更新UpdateLayoutIfNeeded,这样它将返回到原始位置。 (好的方法)
@IBOutlet var horizontalConstraints: NSLayoutConstraint!
@IBOutlet var verticalConstraints: NSLayoutConstraint!
//make active false as the user is dragging the view
horizontalConstraints.isActive = false
verticalConstraints.isActive = false
self.view.layoutIfNeeded()
//make it true again if its not inside any of the other views
horizontalConstraints.isActive = true
verticalConstraints.isActive = true
self.view.layoutIfNeeded()
要么
当用户移动视图时,更新constraints.constant以获取水平和垂直约束(这不是一个好的方法),如果不在其他任何视图内,请再次将其设为零
//make it true again if its not inside any of the other views
horizontalConstraints.constant = change in horizontal direction
verticalConstraints..constant = change in vertical direction
self.view.layoutIfNeeded()
如您所说,编辑设置isActive = false后约束为零,因为
正如苹果博士所说,isActive实际要做的是添加和删除这些约束。
激活或停用约束将在视图上调用addConstraint(:)和removeConstraint(:),该视图是此约束所管理的项目的最接近的共同祖先。使用此属性,而不是直接调用addConstraint(:)或removeConstraint(:)。
因此,使约束成为强引用确实可以解决问题,但我认为为IBOutelet设置强引用不是一个好主意,而以编程方式添加和删除约束则更好。查看此问题解除约束
关于ios - UIButton框架在平移时不会改变,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50579212/