touchBegan和TouchEnded覆盖正在影响另一个UIViewController

时间:2017-02-18 05:43:26

标签: ios swift uiviewcontroller

我有这个UIViewController,其中我已经覆盖了touchBegan和touchEnded函数。我还有一个按钮,用于按下(推)到另一个带有SKView的视图控制器。但是第一个控制器中的覆盖功能仍然是活动的。在那里完成的计算仍然显示在第二个ViewController上。

也许是我缺少的东西,或者我认为这是错误的东西。任何帮助将不胜感激

这是第一个视图控制器

import UIKit
import CoreMotion

class PortraitViewController: UIViewController {

    var vc: UIViewController?
    var startPoint: CGPoint?
    var endPoint: CGPoint?
    var movedPoint: CGPoint?
    var previousMove = CGPoint(x: 0, y: 0)
    var beginTouch: UITouch?
    var scaleSum = 0
    var isPortrait = true
    let DEBUG: Bool = true


    // MARK:
    // MARK: Overriden Variables
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask{return .portrait}
    open override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation{return .portrait}
    override var shouldAutorotate: Bool {return false}


    @IBAction func pinch(_ sender: UIPinchGestureRecognizer) {
        if (isPortrait){
            let scale = sender.scale

            scaleSum += scale.exponent
            print(scaleSum)
            if(scaleSum > 10) {
                scaleSum = 0
                print(">10")
            }

            else if(scaleSum < -10) {
                print("<10")
            }
        }
    }


    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        if(isPortrait){
            if let theTouch = touches.first {
                endPoint = theTouch.location(in: self.view)

                let diffx = (endPoint!.x - startPoint!.x)
                let diffy = (endPoint!.y - startPoint!.y)

                if(diffx != 0 && diffy != 0){
                    let vector = CGVector(dx: diffx, dy: diffy)
                    var angle = atan2(vector.dy, vector.dx) * CGFloat(180.0 / M_PI)
                    if angle < 0 { angle *= -1 } else { angle = 360 - angle }
                } 
            }
        }
        super.touchesEnded(touches, with: event)
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if(isPortrait){
            if let theTouch = touches.first {
                startPoint = theTouch.location(in: self.view)
            }
        }
        super.touchesBegan(touches, with: event)
    }
   //One of my attempts to jerry rig a solution
    @IBAction func prepToLandscape(_ sender: UIBarButtonItem) {
        self.isPortrait = false
        print("isPortrait = \(self.isPortrait)")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewWillAppear(_ animated: Bool) {
        navigationController?.setNavigationBarHidden(true, animated: false)
    }
}

这是第二个视图控制器

import UIKit
import CoreMotion
import SpriteKit

class LandScapeViewController: UIViewController {

    var vc: UIViewController?

    // MARK:
    // MARK: Overriden Variables
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask{return .landscape}
    open override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation{return .landscapeLeft


    // MARK:
    // MARK: Functions
    override func viewDidLoad() {
        super.viewDidLoad()
        let controllerStoryBoard = UIStoryboard(name: "Main", bundle: nil)
        vc = controllerStoryBoard.instantiateViewController(withIdentifier: "Root")

    // Part of my attempt to jerry rig a solution
        let vcP: PortraitViewController = UIStoryboard(name:"Controller",bundle: nil).instantiateViewController(withIdentifier: "PortraitController") as! PortraitViewController
        vcP.isPortrait = false
        print("vcP.isPortrait = \(vcP.isPortrait)")
    }



    override func viewWillAppear(_ animated: Bool) {
        self.view.isMultipleTouchEnabled = true
        let scene = GameScene(size: joystickView.bounds.size)
        scene.backgroundColor = .gray

        if let skView = joystickView as? SKView {
            skView.showsFPS = false
            skView.ignoresSiblingOrder = true
            skView.backgroundColor = .red

            skView.presentScene(scene)
        }
        navigationController?.setNavigationBarHidden(true, animated: false)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    @IBAction func toPortrait(_ sender: UIBarButtonItem) {
        self.dismiss(animated: true, completion: {() -> Void in
    }

}

1 个答案:

答案 0 :(得分:1)

假设显示的代码是一切相关的,这是有道理的。发生的事情是:触摸事件经过了joystickView的测试,但由于您尚未在该视图上实现自定义touchesBegan(_:with:),因此触摸事件会传递到下一个{{1}在响应者链中。那将是UIResponder。但是该类也没有实现自定义LandScapeViewController,因此事件将传递给下一个类,在本例中为touchesBegan(_:with:)。由于PortraitViewController 实现了该方法,因此会调用它。有你的困惑。

要解决此问题,请在PortraitViewController上为touches…UIResponder实施joystickView方法,即使它们什么也不做 - 但不要调用LandScapeViewController } 在他们中!请注意以下touchesBegan(_:with:) documentation

  

如果在不调用super(常用模式)的情况下覆盖此方法,则还必须覆盖其他方法来处理触摸事件,即使您的实现不执行任何操作。

如果您覆盖super,则可能不想致电touchesBegan(_:with:)。这是因为超级实现是“哦,拍摄,我不知道如何处理这个 - 把它传递给链条!”但是当你处理触摸时,它应该在那里结束,因为你正在处理它!所以当你没有处理触摸时只调用super - 在你的情况下看起来像永远不会,至少super

有关详细信息,请查看Event Delivery: The Responder Chain