Swift:通过其超级视图窗口中的平移手势来更改(翻译)UIView位置

时间:2018-09-19 21:15:07

标签: ios swift uiview uigesturerecognizer uipangesturerecognizer

简介

上下文:

在我的主ViewController中,我有一个scrollView,里面有一些对象(它们是UIViews)。当点击/选择其中一个UIView时,我会在UIView中对UITextView进行动画处理,以与所选对象一起使用。 (一次只能显示一个UIView)

出现在对象选择上的UIView被分离为名为AdjunctiveTextView的单独类。

问题/目标:

(下面提供的示例代码将清楚地说明这一点,我也评论了代码中的问题所在)

当一个对象被点击并且有一个带有文本的相邻UIView时,我想让那个相邻的UIView跟在scrollView之后。

  • 我正在使用UIPanGestureRecognizer尝试执行此操作。但是当用户在滚动视图中拖动时,我无法弄清楚如何使其工作。仅当用户在实际的adjunctiveTextView上拖动时才起作用。
  • 一切正常,但在panGesture期间adjunctiveTextView不会更改其位置。
  • 我希望(如果可能的话)将AdjunctiveTextView作为一个单独的类。我的ViewController文件越来越大。

问题:

为什么UIPanGestureRecognizer无法正常工作?要正确翻译backView需要什么?

代码

我的尝试:(如下所示)

我的尝试只是通过panGesture使backView本身“可拖动”。当我滚动scrollView时,什么也没发生。

(我只包含了代码的相关部分)

class ViewController: UIViewController {
    let adjunctiveTextView = AdjunctiveTextView()

    // this is a delegate method which gets called when an object is tapped in the scrollView
    func scrollViewObjectIsTapped(_ objectScrollView: ObjectScrollView, object: AvailableObject) {

   **   adjunctiveTextView.scrollView = scrollView // **Edited! (scrollView is the name of the scrollView in this class too)
        adjunctiveTextView.showView(passInObject: AvailableObject)
    }

}

class AdjunctiveTextView: NSObject {
     lazy var backView: UIView = {
         //backView setup
     }
     lazy var textView: UITextView = {
         //textView setup
     }

      //additional init and setup
 **  weak var scrollView : UIScrollView! // **Edited!
     func showView(passInObject: AvailableObject) {
         if let window = UIApplication.shared.keyWindow {

             // the issue must either be here in the PanGesture setup
             let panG = UIPanGestureRecognizer(target: self, action: #selector(translateView(sender:)))
             panG.cancelsTouchesInView = false
            // window.addGestureRecognizer(panG) 
       **    scrollView.addGestureRecognizer(panG) // **Edited!
             window.addSubview(backView)

             textView.text = passInObject.information
             backView.frame = CGRect(x: passInObject.frame.minX, y: passInObject.minY, width: window.frame.width - passInObject.maxX - 6, height: textView.bounds.height + 5)
             backView.alpha = 0

             //it animates a change of the backViews x position and alpha.
             UIView.animate(withDuration: 0.42, delay: 0, options: .curveEaseInOut, animations: {
                 self.backView.alpha = 1
                 self.backView.frame = CGRect(x: passInObject.frame.minX + passInObject.frame.width, y: passInObject.minY, width: window.frame.width - passInObject.maxX - 6, height: textView.bounds.height + 5)

             }, completion: nil)
         }
     }

     // or the issue is here in the handle function for the PanGesture.
     @objc private func translateView(sender: UIPanGestureRecognizer) {

          if let window = UIApplication.shared.keyWindow {
             let translation = sender.translation(in: window)  //Have tried setting this to scrollView also
             switch sender.state {
             case .began, .changed:
                 backView.center = CGPoint(x: backView.center.x, y: backView.center.y + translation.y)
                 sender.setTranslation(CGPoint.zero, in: window) //Have tried setting this to sccrollView also
                 break
             case .ended:
                 break
             default:
                 break
             }

         }
     }


}

感谢您阅读我的问题。

1 个答案:

答案 0 :(得分:0)

我只是向您的scrollView添加一个弱引用,然后将平移手势添加到scrollView。它可以根据需要工作。如果您想恢复原来的行为,可以考虑向后视图添加另一个平移手势。

class AdjunctiveTextView: NSObject {
lazy var backView: UIView = {
    //backView setup
 return UIView.init()
}()
lazy var textView: UITextView = {
    //textView setup
return UITextView.init(frame: CGRect.init(x: 0, y: 0, width: 300, height: 100))
}()

weak var scrollView: UIScrollView!

//additional init and setup

func showView(passInObject: AvailableObject) {
    if let window = UIApplication.shared.keyWindow {

        // the issue must either be here in the PanGesture setup
        let panG = UIPanGestureRecognizer(target: self, action: #selector(translateView(sender:)))
        panG.cancelsTouchesInView = false
      //  passInObject.addGestureRecognizer(panG)

 scrollView.addGestureRecognizer(panG)

        window.addSubview(backView)

        textView.text = passInObject.information
        textView.backgroundColor = UIColor.blue
        backView.addSubview(textView)

        backView.frame = CGRect(x: passInObject.frame.minX, y: passInObject.frame.minY, width: window.frame.width - passInObject.frame.maxX - 6, height: textView.bounds.height + 5)
        backView.alpha = 0

        //it animates a change of the backViews x position and alpha.
        UIView.animate(withDuration: 0.42, delay: 0, options: .curveEaseInOut, animations: {
            self.backView.alpha = 1
            self.backView.frame = CGRect(x: passInObject.frame.minX + passInObject.frame.width , y: passInObject.frame.minY , width: window.frame.width - passInObject.frame.maxX - 6, height: self.textView.bounds.height + 5)

           self.backView.backgroundColor = UIColor.red

        }, completion: nil)
    }
}

// or the issue is here in the handle function for the PanGesture.
@objc private func translateView(sender: UIPanGestureRecognizer) {

    if let window = UIApplication.shared.keyWindow {
        let translation = sender.translation(in: window)
        switch sender.state {
        case .began, .changed:
            backView.center = CGPoint(x: backView.center.x, y: backView.center.y + translation.y)
            sender.setTranslation(CGPoint.zero, in: window)
            break
        case .ended:
            break
        default:
            break
        }

    }
   }
}


  class ObjectScrollView: UIScrollView{
  }

 class AvailableObject: UIView{
  var information: String!
 }

 class MySCNViewController: UIViewController {

  @IBOutlet weak var oScrollView: ObjectScrollView!

// this is a delegate method which gets called when an object is tapped in the scrollView
  func scrollViewObjectIsTapped(_ objectScrollView: ObjectScrollView, object: AvailableObject) {
    adjunctiveTextView.showView(passInObject: object)
  }

  let  adjunctiveTextView = AdjunctiveTextView()
  let ao =   AvailableObject.init(frame: CGRect.init(x: 0, y: 0, width: 200, height: 200))

  override func viewDidLoad() {
    super.viewDidLoad()
     ao.information = "test"
    adjunctiveTextView.scrollView = oScrollView
      ao.backgroundColor = UIColor.yellow
   }

     @IBAction  func tap(_ sender: Any?){
             scrollViewObjectIsTapped(oScrollView, object: ao)}
   }