gpt4 book ai didi

ios - 如果平移,UIButton 框架不会改变

转载 作者:行者123 更新时间:2023-11-30 11:27:27 24 4
gpt4 key购买 nike

Here is an image of a simple APP I am trying to make

该应用程序有一个针对中心紫色按钮的平移手势识别器,如果该按钮与 4 个橙色按钮中的任何一个相交,则移动该按钮时,紫色按钮会动画并在其相交的按钮范围内移动,否则它将动画返回到初始起始位置,即中心。

第一次平移紫色按钮时,按钮的框架会更新,但如果我第二次尝试,按钮的框架保持不变(位于 View 中心时的值)。

我猜这与我所缺少的自动布局相关,因为如果我删除中心紫色按钮上的约束,则每次平移时框架都会正确更新。

任何人都可以解释一下在使用约束制作动画时我必须记住什么

这是我处理平移手势的代码:

@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()

或者

当用户移动 View 时更新水平和垂直约束的constants(不是一个好方法),如果它不在任何其他 View 内,则再次将其设置为零

//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 实际上做的是添加和删除这些约束,如 Apple 文档所述

Activating or deactivating the constraint calls addConstraint(:) and removeConstraint(:) on the view that is the closest common ancestor of the items managed by this constraint. Use this property instead of calling addConstraint(:) or removeConstraint(:) directly.

因此,使约束强引用确实可以解决问题,但我认为设置对 IBOutelet 的强引用不是一个好主意,以编程方式添加和删除约束更好。查看这个问题解除分配约束

关于ios - 如果平移,UIButton 框架不会改变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50579212/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com