ios - inside - uitapgesturerecognizer swift 4
Swift 3: UIScrollView y(deshabilitar) Reconocedores de gestos (1)
Llego rápido 3 y tengo una clase que es una subclase de UIScrollView. Aquí está:
import SpriteKit
/// Scroll direction
enum ScrollDirection {
case vertical
case horizontal
}
class CustomScrollView: UIScrollView {
// MARK: - Static Properties
/// Touches allowed
static var disabledTouches = false
/// Scroll view
private static var scrollView: UIScrollView!
// MARK: - Properties
/// Current scene
private let currentScene: SKScene
/// Moveable node
private let moveableNode: SKNode
/// Scroll direction
private let scrollDirection: ScrollDirection
/// Touched nodes
private var nodesTouched = [AnyObject]()
// MARK: - Init
init(frame: CGRect, scene: SKScene, moveableNode: SKNode, scrollDirection: ScrollDirection) {
self.currentScene = scene
self.moveableNode = moveableNode
self.scrollDirection = scrollDirection
super.init(frame: frame)
CustomScrollView.scrollView = self
self.frame = frame
delegate = self
indicatorStyle = .white
isScrollEnabled = true
isUserInteractionEnabled = true
//canCancelContentTouches = false
//self.minimumZoomScale = 1
//self.maximumZoomScale = 3
if scrollDirection == .horizontal {
let flip = CGAffineTransform(scaleX: -1,y: -1)
transform = flip
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
/// Began
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
print("begin " + String(CustomScrollView.disabledTouches))
for touch in touches {
let location = touch.location(in: currentScene)
guard !CustomScrollView.disabledTouches else { return }
/// Call touches began in current scene
currentScene.touchesBegan(touches, with: event)
/// Call touches began in all touched nodes in the current scene
nodesTouched = currentScene.nodes(at: location)
for node in nodesTouched {
node.touchesBegan(touches, with: event)
}
}
}
/// Moved
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
print("moved " + String(CustomScrollView.disabledTouches))
for touch in touches {
let location = touch.location(in: currentScene)
guard !CustomScrollView.disabledTouches else { return }
/// Call touches moved in current scene
currentScene.touchesMoved(touches, with: event)
/// Call touches moved in all touched nodes in the current scene
nodesTouched = currentScene.nodes(at: location)
for node in nodesTouched {
node.touchesMoved(touches, with: event)
}
}
}
/// Ended
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
let location = touch.location(in: currentScene)
guard !CustomScrollView.disabledTouches else { return }
/// Call touches ended in current scene
currentScene.touchesEnded(touches, with: event)
/// Call touches ended in all touched nodes in the current scene
nodesTouched = currentScene.nodes(at: location)
for node in nodesTouched {
node.touchesEnded(touches, with: event)
}
}
}
/// Cancelled
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
print("cancelled " + String(CustomScrollView.disabledTouches))
for touch in touches {
let location = touch.location(in: currentScene)
guard !CustomScrollView.disabledTouches else { return }
/// Call touches cancelled in current scene
currentScene.touchesCancelled(touches, with: event)
/// Call touches cancelled in all touched nodes in the current scene
nodesTouched = currentScene.nodes(at: location)
for node in nodesTouched {
node.touchesCancelled(touches, with: event)
}
}
}
}
// MARK: - Touch Controls
extension CustomScrollView {
/// Disable
class func disable() {
CustomScrollView.scrollView?.isUserInteractionEnabled = false
CustomScrollView.disabledTouches = true
}
/// Enable
class func enable() {
CustomScrollView.scrollView?.isUserInteractionEnabled = true
CustomScrollView.disabledTouches = false
}
}
// MARK: - Delegates
extension CustomScrollView: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollDirection == .horizontal {
moveableNode.position.x = scrollView.contentOffset.x
} else {
moveableNode.position.y = scrollView.contentOffset.y
}
}
}
Su función principal es crear un menú desplazable, y en su mayor parte funciona. Creo un objeto en GameScene, y cómo se supone que funciona es que cuando se registra un toque, se invocan las funciones táctiles anuladas (touchBegan, touchMoved, etc.) en CustomScrollView, que luego llaman a las funciones táctiles en GameScene. Esto sucede, el menú se desplaza bien y se invocan los métodos de GameScene.
El truco es que mis funciones anuladas (y GameScene) solo se invocan cuando estás deslizando horizontalmente. Cuando desliza hacia arriba o hacia abajo (más allá de cierto grado), el menú aún se desplaza, pero creo que se llama a los métodos táctiles de UIScrollView.
Cuando deslizas verticalmente, se llama a mi método TouchCancelled, lo que me hace pensar que esto tiene algo que ver con los reconocedores de gestos de UIScrollView (el reconocedor de barrido / arrastre creo) disparando cuando no deberían.
¿Es este el caso? Si es así, ¿puedo desactivar el reconocedor? Y si puedo, ¿debería? En una nota lateral, ¿es esta la mejor (o al menos aceptable) forma de implementar UIScrollView para que los métodos táctiles de GameScene todavía se llamen?
Si los reconocedores de gestos conflictivos necesitan ser reconocidos simultáneamente, puede hacer uso de gestureRecognizer (_: shouldRecognizeSimultaneouslyWith :) ,