问题
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 :
You must subclass from the
UIScrollView
class as you did in your classPassTouchesScrollView
and implement the delegate pattern to be notified about theUIScrollView
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) } } }
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") } }
You must be in the Interface Builder select your
UIScrollView
and set the class for it as your classPassTouchesScrollView
, 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