Reputation: 181
I am confused on how touches trickle upwards to parent views. To test I built a simple program that has 4 UIButtons. The Button class sends the touch events upwards:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
for var i=0; i<4; i++ {
let button = Button(type: UIButtonType.System) as Button
button.frame = CGRectMake(0,0,200,100)
button.center = CGPoint(x: i*250+100,y: 50)
button.setTitle(String(i), forState: UIControlState.Normal)
self.view.addSubview(button)
}
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
print("ViewController touchesBegan",touches.count)
for touch in touches {
print(touch.locationInView(self.view).x,touch.locationInView(self.view).y)
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
print("ViewController touchesMoved",touches.count)
for touch in touches {
print(touch.locationInView(self.view).x,touch.locationInView(self.view).y)
}
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
print("ViewController touchesEnded",touches.count)
for touch in touches {
print(touch.locationInView(self.view).x,touch.locationInView(self.view).y)
}
}
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
print("ViewController touchesCancelled")
}
}
class Button : UIButton {
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
print("button",self.center,"touchesBegan")
self.nextResponder()?.touchesBegan(touches, withEvent: event)
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
print("button",self.center,"touchesEnded")
self.nextResponder()?.touchesEnded(touches, withEvent: event)
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
print("button",self.center,"touchesMoved")
self.nextResponder()?.touchesMoved(touches, withEvent: event)
}
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
print("button",self.center,"touchesCancelled")
self.nextResponder()?.touchesCancelled(touches, withEvent: event)
}
override func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) {
if (self.focused) {
print("button",self.center,"YES didUpdateFocus")
} else {
print("button",self.center,"NO didUpdateFocus")
}
}
}
What I had expected was that ALL touch-related items would show up in the ViewControllers touch handlers, but they do not. A simple shift right using the tvOS remote shows the following:
button (100.0, 50.0) YES didUpdateFocus
button (100.0, 50.0) touchesBegan
ViewController touchesBegan 1
100.0 50.0
button (100.0, 50.0) touchesMoved
ViewController touchesMoved 1
116.728515625 50.0
button (100.0, 50.0) touchesMoved
button (100.0, 50.0) touchesMoved
button (100.0, 50.0) touchesMoved
button (100.0, 50.0) touchesMoved
button (100.0, 50.0) touchesMoved
button (100.0, 50.0) touchesMoved
button (100.0, 50.0) NO didUpdateFocus
button (350.0, 50.0) YES didUpdateFocus
button (100.0, 50.0) touchesMoved
button (100.0, 50.0) touchesMoved
button (100.0, 50.0) touchesMoved
button (100.0, 50.0) touchesMoved
button (100.0, 50.0) touchesMoved
button (100.0, 50.0) touchesMoved
button (100.0, 50.0) touchesEnded
Why do I NOT see "ViewController touchesMoved" after all of the "button touchesMoved" notices?
I presume it is because the button that originated the touch is no longer "in focus" so the parent view ignores the touch responder .. but then (i) why don't some of the moves show up in the viewcontroller before the button loses focus, and (ii) why does the button that IS in focus not show a touchesMoved and send that message up to the ViewController?
Thanks so much for any light someone can shed on this.
Jim
Upvotes: 3
Views: 548