UIStackView&手势

时间:2017-10-23 06:31:55

标签: ios uigesturerecognizer uistackview

在我用平移手势移动它之后,我正试图获取/保持我的UIStackView中的元素。

例如,我试图抓住句柄的元素就是按钮标记或文本标签文本。

代码解释......

我正在通过函数func createButtonStack(label: String, btnTag: Int) -> UIStackView

创建一个UIStackView

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

创建按钮堆栈时,我会将平移手势附加到其上,以便我可以在屏幕上移动按钮。以下3点有效。

  1. 我创建了按钮堆栈
  2. 我可以按下按钮并打电话给我打印消息。
  3. 我可以移动按钮堆栈。
  4. 我遇到的问题是......

    第一次移动按钮堆栈并触发if语句gesture.type == .ended行时,我失去了对按钮堆栈的控制。

    也就是说,按钮按下不再工作,也不能再将其移动。

    有人可以帮忙吗?感谢

    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)
        }
    

2 个答案:

答案 0 :(得分:1)

如果您在buttonStack上使用自动布局,则无法直接操纵guestureView.center centerX。您必须使用约束来实现拖动效果。 因此,除了ButtonStack.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true之外,你应该采取以下措施:

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

为此,您应该在NSLayoutConstraint类上声明类型为ButtonStack的弱属性。你可以为centerY约束做同样的事情。

func pan(guesture: UIPanGestureRecognizer)方法中,您可以直接在ButtonStack视图上操作centerXConstraintcenterYConstraint属性。

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

答案 1 :(得分:0)

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

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

一旦我移动了一个按钮,它就有效地打破了UIStackView,我失去了对移动按钮的控制。

这里的解决方法是从UIStackView中取出三个按钮,现在我可以移动并控制所有三个按钮而不会出现问题。

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

移动元素后,平移的.ended操作可以访问.tag,因此可以识别移动了哪个按钮堆栈。

再次感谢所有输入。