Subclass UIScrollView in Swift for touches Began & touches Moved

强颜欢笑 提交于 2020-01-01 12:10:03

问题


I'm using Swift 1.2

I'm trying to use this UIScrollview touchesbegan,touchesmoved,touchesended actions and the link in the 2nd comment of the accepted answer.

I'm using a storyboard with auto layout, I set my custom class for the UIScrollView in Custom Class.

I'm not receiving either of these touch events in the UIViewController that contains my custom UIScrollView

Edit: Updated my code for how I use it with @Victor Sigler 's answer.

Custom ScrollView Code:

import UIKit

protocol PassTouchesScrollViewDelegate {

func scrollTouchBegan(touches: Set<NSObject>, withEvent event: UIEvent)
func scrollTouchMoved(touches: Set<NSObject>, withEvent event: UIEvent)
}

class PassTouchesScrollView: UIScrollView {

var delegatePass : PassTouchesScrollViewDelegate?

override init(frame: CGRect) {
    super.init(frame: frame)
}

required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {

    self.delegatePass?.scrollTouchBegan(touches, withEvent: event)


}

override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {

    self.delegatePass?.scrollTouchMoved(touches, withEvent: event)

}

}

My ViewController:

import UIKit

class ViewController: UIViewController, PassTouchesScrollViewDelegate {

@IBOutlet weak var scrollView: UIScrollView!

override func viewDidLoad() {
    super.viewDidLoad()

    scrollView.delegatePass = self
}

func scrollTouchBegan(touches: Set<NSObject>, withEvent event: UIEvent)    {

    println("began \(touches)")

}

func scrollTouchMoved(touches: Set<NSObject>, withEvent event: UIEvent)      {

    println("moved \(touches)")
}     

}

I'm trying to let a user draw a line over a UIImage, which I got working using a PanGesture Recognizer but the performance was very poor, especially on older hardware, I followed a Ray Wenderlich tutorial that used touches Began and the performance was much better, however it was on a UIView and not a ScrollView. I need a UIScrollView since prior to a user drawing on an image they can zoom in and around it.


回答1:


You're thinking about this wrong. If you want to know when a UIScrollView is moving, there's no need to subclass it. iOS has set up all the methods you need inside of the UIScrollViewDelegate.

You must implement the UISCrollViewDelegate to be notified about the actions in the UIScrollView and set the delegate by Interface Builder or in code, is up to you.

See the following example to know how to do it for example :

class ViewController: UIViewController, UIScrollViewDelegate {

     @IBOutlet weak var scrollView: UIScrollView!

     override func viewDidLoad() {
       super.viewDidLoad()
       self.scrollView.delegate = self
     }
}

Still if you want to know how its touched in the way you explained above you must follow the following steps :

  1. You must subclass from the UIScrollView class as you did in your class PassTouchesScrollView and implement the delegate pattern to be notified about the UIScrollView in the following way:

    import UIKit
    
    protocol PassTouchesScrollViewDelegate {
       func touchBegan()
       func touchMoved()
    }
    
    
    class PassTouchesScrollView: UIScrollView {
    
      var delegatePass : PassTouchesScrollViewDelegate?
    
      override init(frame: CGRect) {
        super.init(frame: frame)
      }
    
      required init(coder aDecoder: NSCoder) {
         super.init(coder: aDecoder)
      }
    
      override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    
         // Notify it's delegate about touched
         self.delegatePass?.touchBegan()
    
        if self.dragging == true {
           self.nextResponder()?.touchesBegan(touches, withEvent: event)
        } else {
           super.touchesBegan(touches, withEvent: event)
        }
    
     }
    
      override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent)  {
    
         // Notify it's delegate about touched
         self.delegatePass?.touchMoved()
    
         if self.dragging == true {            
            self.nextResponder()?.touchesMoved(touches, withEvent: event)
         } else {            
           super.touchesMoved(touches, withEvent: event)
         }
      }   
    }
    
  2. Your class ViewController must be implemented in the following way:

    class ViewController: UIViewController, UIScrollViewDelegate {
    
      @IBOutlet weak var scrollView: PassTouchesScrollView!
    
      override func viewDidLoad() {
        super.viewDidLoad()        
        scrollView.delegate = self  
        scrollView.delegatePass = self      
      }
    
      override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
      }
    
      func touchMoved() {
         println("touch moved")
      }
    
      func touchBegan() {
         println("touch began")
      }
    
    }
    
  3. You must be in the Interface Builder select your UIScrollView and set the class for it as your class PassTouchesScrollView, in the Identity Inspector in the class part.

And you should see in your console the following:

touch began
touch began
touch began
touch began
touch began
touch began
touch moved
touch move

I hope this help you.




回答2:


try this

  extension UIScrollView {

    override open func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.next?.touchesBegan(touches, with: event)
        print("touchesBegan")
    }

    override open func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.next?.touchesMoved(touches, with: event)
        print("touchesMoved")
    }

    override open func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.next?.touchesEnded(touches, with: event)
        print("touchesEnded")
    }

}



回答3:


touchesBegan only works on a subclass of UIView. Take it out of your UIViewController to make it work.

UIResponder Apple Docs



来源:https://stackoverflow.com/questions/29799529/subclass-uiscrollview-in-swift-for-touches-began-touches-moved

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!