Subclass of UIScrollView in Swift for Beginning touches and touching movements
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.
source to share
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 classPassTouchesScrollView
and implement the delegate pattern for notificationUIScrollView
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 classPassTouchesScrollView
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.
source to share
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")
}
}
source to share