ios - touchBegan 和 TouchEnded 重写正在影响另一个 UIViewController

标签 ios swift uiviewcontroller

我有这个 UIViewController,我在其中覆盖了 touchBegan 和 touchEnded 函数。我还有一个按钮,它可以将(推送)到另一个带有 SKView 的 View Controller 。但是第一个 Controller 中的覆盖功能仍然有效 ei。在那里完成的计算仍然显示在第二个 ViewController 上。

也许我遗漏了什么或者我认为那是错误的。任何帮助将不胜感激

这是第一个 View Controller

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

这是第二个 View Controller

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
    }

}

最佳答案

假设显示的代码是相关的,这是有道理的。发生的事情是这样的:触摸事件对 joystickView 进行了 HitTest ,但是因为您还没有在该 View 上实现自定义 touchesBegan(_:with:),触摸事件被传递到响应链中的下一个 UIResponder。那就是 LandScapeViewController。但是该类也没有实现自定义 touchesBegan(_:with:),因此事件传递给下一个类,在本例中为 PortraitViewController。因为 PortraitViewController 确实 实现了那个方法,它被调用了。这是你的困惑。

要解决此问题,请为 joystickViewLandScapeViewControllerUIResponder 上实现 touches... 方法,即使它们什么都不做——但不要在其中调用 super!请注意以下内容,来自 touchesBegan(_:with:) documentation :

If you override this method without calling super (a common use pattern), you must also override the other methods for handling touch events, even if your implementations do nothing.

在覆盖 touchesBegan(_:with:) 的地方,您可能不想调用 super。这是因为 super 实现会说“哦,糟糕,我不知道如何处理这个——把它向上传递!”但是当你处理触摸时,它应该到此为止,因为 你正在处理它! 所以只在你不处理触摸时调用 super - 在你的情况下看起来从来没有,至少对于 PortraitViewController 是这样。

有关更多信息,请查看 Event Delivery: The Responder Chain .

关于ios - touchBegan 和 TouchEnded 重写正在影响另一个 UIViewController,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42311534/

相关文章:

ios - iOS 上的 IOBluetooth/使用其 Mac 地址连接到设备?

iphone - UIViewController 在新的 ARC 内存管理下没有被释放

ios - 转至 UIViewController 而不初始化新对象

ios - 推送和弹出 UIViewController 时导致灰色、模糊区域的原因

swift - 在 Swift 中用两个符号分割字符串

iphone - iOS成长动画CGAffineTransformMakeScale移动

ios - Google 街景应用程序(非 Google map )的 URL 架构

ios - 将视频分成 30 秒的 block Ios swift 5

ios - 单个 viewController 上的多个自定义选择器 View

ios - 核心 Spotlight API - 搜索结果中的 kUTTypeAudio 播放按钮