2016-11-27 3 views
1

신속한 3입니다. UIScrollView의 하위 클래스입니다. 여기있다 :스위프트 3 : UIScrollView 및 (비활성화) 제스처 인식 자

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 
     } 
    } 
} 

그것은 주요 기능은 스크롤 메뉴를 만드는 것입니다, 그리고 대부분의 경우 그것은 작동합니다. GameScene에서이 객체를 만들고 어떻게 작동해야하는지는 터치가 등록되면 CustomScrollView에서 오버라이드 된 터치 함수 (touchBegan, touchMoved 등)가 호출되어 GameScene에서 터치 함수를 호출한다는 것입니다. 이런 일이 발생하면 메뉴가 제대로 스크롤되고 GameScene의 메소드가 호출됩니다.

캐치는 내 오버라이드 기능이며 GameScene 's는 가로로 스 와이프 할 때만 호출됩니다. 특정 위도를지나 위 또는 아래로 스 와이프하면 메뉴가 계속 스크롤되지만 UIScrollView의 터치 메소드가 호출된다고 생각합니다.

세로로 스 와이프하면 touchCancelled 메서드가 호출되어 UIScrollView의 제스처 인식기 (팬/드래그 인식기라고 생각합니다)가 아닌 경우 발생시키는 것으로 생각됩니다.

이 경우입니까? 그렇다면 인식기를 사용 중지 할 수 있습니까? 내가 할 수 있다면 할 수 있을까요? 참고로 GameScene의 터치 메소드가 여전히 호출되도록 UIScrollView를 구현하는 가장 좋은 방법인가요?

답변