inside ios swift cocoa-touch uiscrollview uigesturerecognizer

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?