Subclass of UIScrollView in Swift for Beginning touches and touching movements

enter image description here I am using Swift 1.2

I'm trying to use this UIScrollview touchhesbegan, touchhesmoved, touchhesended actions and the link in the second comment of the accepted answer.

I am using auto layout storyboard, I am setting my own class for UIScrollView in custom class.

I am not getting any of these touch events in the UIViewController that my custom UIScrollView contains

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

Custom scroll 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 the user draw a line over a UIImage that I was working with using PanGesture Recognizer, but the performance was very poor, especially on older hardware, I followed Ray Wenderlich's tutorial which used strokes. performance was much better however it was on UIView and not on ScrollView. I need a UIScrollView since up to the user drawn on the image it is possible to scale it in and around it.

+3


source to share


3 answers


I thought you were thinking about it the wrong way. If you want to know when it is moving UIScrollView

, there is no need to subclass it. iOS has configured all the methods you need internally UIScrollViewDelegate

.

You must implement UIScrollViewDelegate

to receive action notifications in UIScrollView

and set delegate

in Interface Builder or in code. you.

Refer to the following example for how to do this, for example:

class ViewController: UIViewController, UIScrollViewDelegate {

     @IBOutlet weak var scrollView: UIScrollView!

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

      

However, if you want to know how the above methods affected it, you should follow these steps:



  • You must subclass from the class UIScrollView

    as you did in your class PassTouchesScrollView

    and implement the delegate pattern for notification UIScrollView

    like this:

    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 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 delegate about touched
         self.delegatePass?.touchMoved()
    
         if self.dragging == true {            
            self.nextResponder()?.touchesMoved(touches, withEvent: event)
         } else {            
           super.touchesMoved(touches, withEvent: event)
         }
      }   
    }
    
          

  • Your class ViewController

    should be implemented like this:

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

  • You should be in the interface builder, select yours UIScrollView

    and set the class for it as your class PassTouchesScrollView

    in the identity inspector in the class part.

And you should see the following on your console:

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

      

Hope this helps you.

+5


source


touchesBegan

only works in subclass UIView

. Take it out of your UIViewController for it to work.



UIResponder Apple Docs

0


source


try it

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

}

      

0


source







All Articles