Ios 视觉与手势

Ios 视觉与手势,ios,uigesturerecognizer,uistackview,Ios,Uigesturerecognizer,Uistackview,在我用平移动作移动视图后,我试图获取/保持视图中元素的控制柄 例如,我试图抓住句柄的元素是按钮标记或文本标签文本之类的东西 代码解释了 我正在通过函数func createButtonStacklabel:String,btnTag:Int->UIStackView创建一个UIStackView 它包含一个按钮和一个文本标签 创建按钮堆栈时,我会在其上附加一个平移手势,以便在屏幕上移动按钮。以下三点很有效 我创建了按钮堆栈 我可以按下按钮,然后打电话给娱乐公司打印我的信息。 我可以移动按钮堆栈。

在我用平移动作移动视图后,我试图获取/保持视图中元素的控制柄

例如,我试图抓住句柄的元素是按钮标记或文本标签文本之类的东西

代码解释了

我正在通过函数func createButtonStacklabel:String,btnTag:Int->UIStackView创建一个UIStackView

它包含一个按钮和一个文本标签

创建按钮堆栈时,我会在其上附加一个平移手势,以便在屏幕上移动按钮。以下三点很有效

我创建了按钮堆栈 我可以按下按钮,然后打电话给娱乐公司打印我的信息。 我可以移动按钮堆栈。 我的问题是

一旦我第一次移动按钮堆栈并且触发了if语句signature.type=.end行,我就失去了对按钮堆栈的控制

也就是说,按下按钮不再有效,我也不能再移动它了

有人能帮忙吗?谢谢

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .lightGray

        let ButtonStack = createButtonStack(label: “Button One”, btnTag: 1)

        view.addSubview(ButtonStack)

        ButtonStack.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
        ButtonStack.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true

        let panGuesture = UIPanGestureRecognizer(target: self, action: #selector(pan(guesture:)))

        ButtonStack.isUserInteractionEnabled = true
        ButtonStack.addGestureRecognizer(panGuesture)
    }

    func createButtonStack(label: String, btnTag: Int) -> UIStackView {

        let button = UIButton()
        button.setImage( imageLiteral(resourceName: "star-in-circle"), for: .normal)
        button.heightAnchor.constraint(equalToConstant: 100.0).isActive = true
        button.widthAnchor.constraint(equalToConstant: 100.0).isActive = true
        button.contentMode = .scaleAspectFit
        button.tag = btnTag

        switch btnTag {
        case 1:
            button.addTarget(self, action: #selector(printMessage), for: .touchUpInside)
        case 2:
            break
        default:
            break
        }

        //Text Label
        let textLabel = UILabel()
        textLabel.backgroundColor = UIColor.green
        textLabel.widthAnchor.constraint(equalToConstant: 100.0).isActive = true
        textLabel.heightAnchor.constraint(equalToConstant: 25.0).isActive = true
        textLabel.font = textLabel.font.withSize(15)
        textLabel.text = label
        textLabel.textAlignment = .center

        //Stack View
        let buttonStack = UIStackView()
        buttonStack.axis  = UILayoutConstraintAxis.vertical
        buttonStack.distribution  = UIStackViewDistribution.equalSpacing
        buttonStack.alignment = UIStackViewAlignment.center
        buttonStack.spacing   = 1.0

        buttonStack.addArrangedSubview(button)
        buttonStack.addArrangedSubview(textLabel)
        buttonStack.translatesAutoresizingMaskIntoConstraints = false

        return buttonStack
    }

   @objc  func printMessage() {
        print(“Button One was pressed”)
    }

    @objc func pan(guesture: UIPanGestureRecognizer) {
        let translation = guesture.translation(in: self.view)

        if let guestureView = guesture.view {
            guestureView.center = CGPoint(x: guestureView.center.x + translation.x, y: guestureView.center.y + translation.y)

            if guesture.state == .ended {                
                print("Guesture Center - Ended = \(guestureView.center)")
            }
        }
        guesture.setTranslation(CGPoint.zero, in: self.view)
    }

如果在按钮堆栈上使用自动布局,则无法直接操作guestureView.center centerX。必须使用约束才能实现拖动效果。 因此,您不应使用ButtonStack.centerXAnchor.constraintequalTo:self.view.centerXAnchor.isActive=true,而应按照以下步骤执行操作:

let centerXConstraint = ButtonStack.centerXAnchor.constraint(equalTo: self.view.centerXAnchor)
centerXConstraint.isActive = true
ButtonStack.centerXConstraint = centerXConstraint
要这样做,您应该在ButtonStack类上声明NSLayoutConstraint类型的弱属性。可以对中心约束执行相同的操作

之后,在func-panguesture:uipangestruerecognizer方法中,您可以直接在ButtonStack视图上操作centerXConstraint和centerYConstraint属性


此外,我发现您没有在ButtonStack上将TranslatesAutoResizezingMaskinToConstraints属性设置为false。无论何时以编程方式使用autolayout,都应该这样做

感谢PGDev和marosoaie的投入。两者都为我提供了解决这个问题的思路

我的代码只使用了一个按钮,但我的项目在一个视图中有三个按钮

一旦我移动了一个按钮,它实际上破坏了视图,我失去了对移动按钮的控制

这里的修复方法是将这三个按钮从UIStackView中移除,我现在可以毫无问题地移动和控制这三个按钮

至于在按钮/文本字段UIStackView上保留一个句柄,这是通过向UIStackView添加一个.tag来实现的

一旦我移动了元素,pan的.end操作就可以访问.tag,从而允许我识别移动了哪个按钮堆栈


再次感谢您的所有输入。

我已经执行了您发布的相同代码。它工作得非常好。即使在将堆栈视图移动到另一个位置后,我也可以毫无问题地点击按钮。@PGDev。谢谢你的洞察力。它给了我一些思考的东西,事实上我的一个按钮正在正常工作。我真正的项目有多个按钮,它们“应该”以相同的方式运行,但在它们被移动后不会。我将仔细研究代码的其余部分,并试图找出为什么一个按钮可以工作,而不是多个按钮。谢谢marosoaie,我将研究弱NSLayoutConstraint属性的使用。对于buttonStack上的translatesAutoresizingMaskIntoConstraints=false,在createButtonStack函数中返回buttonStack之前,我在第行中设置了它。