Swift: изменение (перевод) положения UIView с помощью жеста панорамирования в его окне суперпредставления - PullRequest
0 голосов
/ 20 сентября 2018

Введение

Контекст:

В моем главном ViewController у меня есть scrollView с несколькими объектами внутри (которые являются UIViews).Когда один из UIViews касается / выбирается, я анимирую UITextView в UIView, чтобы перейти к выбранному объекту.(одновременно может отображаться только один UIView)

Этот UIView, который появляется при выборе объекта, разделен на отдельный класс с именем AdjunctiveTextView.

Проблема / цель:

(приведенный ниже пример кода прояснит это, я также прокомментировал, где проблема заключается в коде)

Когда объект коснулся и имеет смежный UIView с текстом, я хочу, чтобы этот смежный UIView следовал за scrollView.

  • Я использую UIPanGestureRecognizer, чтобы попытаться сделать это.Но я не могу понять, как заставить это работать, когда пользователь перетаскивает в просмотре прокрутки.Это работает, только если пользователь перетаскивает фактическое adjunctiveTextView.
  • Все работает, как и ожидалось, за исключением того, что adjunctiveTextView не меняет свою позицию во время panGesture.
  • Я бы хотел (если возможно) иметь AdjunctiveTextView в качестве отдельного класса.Мой файл ViewController становится довольно большим.

Вопрос:

Почему UIPanGestureRecognizer не работает должным образом?Что нужно для правильного перевода backView?

Код

Моя попытка: (как показано ниже)

Моя попытка просто делаетсам backView «перетаскивается» через panGesture.С прокруткой 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 голосов
/ 20 сентября 2018

Я просто добавляю слабую ссылку к вашему 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)}
   }
...