【问题标题】:iOS: dragging the copy of a buttoniOS:拖动按钮的副本
【发布时间】:2017-01-29 18:06:44
【问题描述】:

我不确定是否有人问过这个问题,但我没有找到解决方案。我在一个按钮上实现平移手势,但想法是:按钮固定在一个位置,当用户拖动它时,会创建一个按钮的副本并随着手势移动;原来的保留在其初始位置(因此视图中将有 2 个按钮)。当平移结束时,新按钮用于一些处理,然后它应该消失(原来的保持原样;所以整个过程可以重复)。目前我所拥有的如下:

private func addPanGesture() {
    for btn in self.selectors { //selectors is a list of buttons which needs this gesture
        let pan = UIPanGestureRecognizer(target: self, action:#selector(self.panDetected(_:)))
        pan.minimumNumberOfTouches = 1
        pan.maximumNumberOfTouches = 1
        btn.addGesturerecognizer(pan)
    }
}

@objc private func panDetected(_ panGesture: UIPanGestureRecognizer) {
    var translation = panGesture.translation(in: view)
    panGesture.setTranslation(CGPoint(x: 0, y: 0), in: view)

    var newButton = UIButton()
    if let initButton = panGesture.view as? UIButton {
        print ("Button recognized!") // this msg is printed out
        newButton.center = CGPoint(x: initButton.center.x + translation.x, y: initButton.center.y + translation.y)
        newButton.setImage(UIImage(named: "somename"), for: .normal)
    }

    if panGesture.state == UIGestureRecognizerState.began {
        self.view.addSubview(newButton)
    }
    if panGesture.state == UIGestureRecognizerState.ended {
        //some other processing
    }
    if panGesture.state == UIGestureRecognizerState.changed {
        self.view.addSubview(newButton)
    }
    // printed-out msgs show began, ended, changed states have all been reached
}

但新按钮并没有出现在我的视图中。我可以知道如何解决这个问题吗?

【问题讨论】:

    标签: ios uibutton uipangesturerecognizer


    【解决方案1】:
    1. 您只需要在.began 上创建新按钮并将其添加为子视图,然后在.ended 上将其删除。
    2. 因此您需要保留对新按钮的引用。
    3. 您正在设置新按钮的中心,但没有设置它的大小。你可以设置它的.frame
    4. 您不需要为平移手势设置翻译。当您收到var translation = panGesture.translation(in: view) 时,您将获得所需的一切。
    5. 我只为一个按钮编写了以下代码,但如果您要允许同时拖动按钮,则需要保留移动按钮列表而不是var movingButton: UIButton?

          private func addPanGesture() {
              let pan = UIPanGestureRecognizer(target: self, action:#selector(self.panDetected(_:)))
              pan.minimumNumberOfTouches = 1
              pan.maximumNumberOfTouches = 1
              btn.addGestureRecognizer(pan)
          }
      
          @objc private func panDetected(_ panGesture: UIPanGestureRecognizer) {
              let translation = panGesture.translation(in: view)
      
              let initButton = panGesture.view as! UIButton
      
      
              if panGesture.state == UIGestureRecognizerState.began {
                  // this is just copying initial button
                  // this might be overkill
                  // just make sure you set the frame, title and image of the new button correctly
                  let initButtonData = NSKeyedArchiver.archivedData(withRootObject: initButton)
                  let newButton = NSKeyedUnarchiver.unarchiveObject(with: initButtonData) as! UIButton
      
                  // we store new button's reference since we will just move it while it is added to view
                  movingButton = newButton
                  self.view.addSubview(movingButton!)
      
              }
              if panGesture.state == UIGestureRecognizerState.ended {
                  //some other processing
      
                  // when we are done just we just remove it from superview
                  movingButton!.removeFromSuperview()
              }
              if panGesture.state == UIGestureRecognizerState.changed {
      
                  // at any change, all we need to do is update movingButton's frame
                  var buttonFrame = initButton.frame;
                  buttonFrame.origin = CGPoint(x: buttonFrame.origin.x + translation.x, y: buttonFrame.origin.y + translation.y)
                  movingButton!.frame = buttonFrame
              }
          }
      

    【讨论】:

      【解决方案2】:

      不调试很难说,但我看到了一些东西:

      您每次通过 panDetected 创建一个新按钮,并每次将其添加到视图中。您应该只在 .began 状态下创建添加按钮。

      您应该使用init(frame:) 创建您的按钮,并将其初始化为图像的大小。

      看起来您正在将平移手势附加到按钮上。然后你得到按钮坐标系中的平移坐标,这没有意义。您应该将平移手势转换为按钮的超级视图的坐标系,并且不应调用 setTranslation,除非平移手势的状态为 .began

      您应该在每次收到 1st.changed` 消息时将按钮的坐标设置为平移手势的新位置。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-22
        • 2012-07-14
        • 1970-01-01
        • 2014-04-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多