Ios UIButton框架没有';淘金不换钱

Ios UIButton框架没有';淘金不换钱,ios,swift,autolayout,uipangesturerecognizer,Ios,Swift,Autolayout,Uipangesturerecognizer,该应用程序有一个用于中央紫色按钮的平移手势识别器,如果按钮与4个橙色按钮中的任何一个相交,则移动按钮时,紫色按钮将在其相交的按钮边界内进行动画和移动,否则将动画移回初始起始位置,即中央 第一次平移紫色按钮时,按钮的边框会更新,但如果第二次尝试,按钮的边框将保持不变(位于视图中心时的值) 我猜这与我缺少的自动布局有关,因为如果我删除中间紫色按钮上的约束,如果我平移,框架每次都会正确更新 有人能解释一下在设置约束动画时我必须记住什么吗 以下是我处理平移手势的代码: @objc func handle

该应用程序有一个用于中央紫色按钮的平移手势识别器,如果按钮与4个橙色按钮中的任何一个相交,则移动按钮时,紫色按钮将在其相交的按钮边界内进行动画和移动,否则将动画移回初始起始位置,即中央

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

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

有人能解释一下在设置约束动画时我必须记住什么吗

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

@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,并根据需要更新UpdateLayoutIf,这样它将返回到原始位置。(好办法)

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

//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后,约束为零,因为 iActive实际做的是像Apple doc所说的那样添加和删除这些约束

激活或停用约束将在视图上调用addConstraint(:)和removeConstraint(:),该视图是此约束管理的项的最接近的公共祖先。使用此属性,而不是直接调用addConstraint(:)或removeConstraint(:)


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

您对紫色按钮有哪些约束?@iraniyaneyanesh中心水平和垂直范围行为(如果我采用第二种方法)。。将isActive设置为false将使约束变量变为nil。。。。因此,我无法再次将其设置为true。通过使插座变强而不是变弱解决了此问题,谢谢您的帮助您还应该更新您的答案是的,我使用示例项目检查它变为零,我已在早期进行了此设置。isActive true/false我从未获得零可能是因为我以前以编程方式创建,
//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()