SplitViewController GestureRecognizer效果触及屏幕的左边缘

时间:2019-02-23 18:34:42

标签: ios swift uisplitviewcontroller touchesbegan touchesended

我有一个可在iPhone和iPad上运行的应用程序,并使用了UISplitViewController,我将其折叠在iPhone上,并使用导航项在“主视图”和“细节”视图控制器之间移动。在detailViewController上,我有一个大的正方形视图,覆盖了iPhone的宽度,减去了一些边距。该视图接收touchesBegan,tackedEnded,tap,doubleTap和longTap事件,供在应用程序中使用。

最近,在执行一些UITest代码时,我发现在iPhone 6 Plus模拟器的屏幕左侧附近出现了不必要的touchedEnded事件。后来我发现,在iPhone 8 Plus和iPhone XR上,我没有得到touchesBegan或touchesEnded事件。超出显示屏的第40点,一切正常。然后,我发现2x设备在10pt之前有此问题,但是大部分被我的边缘余量吸收了。 iPad即使在纵向折叠模式下也完全没有此问题。

我解构了我的App,发现它在我使用SplitViewController时发生。然后,我在一个测试用例中重新创建了问题,在该用例中,我创建了一个Master-Detail App,并将视图添加到detailViewController视图,并将其命名为GameInputView,然后添加了以下文件:

//
//  GameInputView.swift

import UIKit

private var debug:String? = String()

class GameInputView:UIView {

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!

        self.isExclusiveTouch = true

        let tapRecognizer1 = UILongPressGestureRecognizer(target: self, action:#selector(gameboardPressed(_:)))
        tapRecognizer1.numberOfTouchesRequired = 1

        self.addGestureRecognizer(tapRecognizer1)

        let tapRecognizer2 = UITapGestureRecognizer(target: self, action:#selector(gameboardDoubleTapped(_:)))
        tapRecognizer2.require(toFail: tapRecognizer1)
        tapRecognizer2.numberOfTapsRequired = 2

        self.addGestureRecognizer(tapRecognizer2)

        let tapRecognizer3 = UITapGestureRecognizer(target: self, action:#selector(gameboardTapped(_:)))
        tapRecognizer3.numberOfTapsRequired = 1
        tapRecognizer3.require(toFail: tapRecognizer2)

        self.addGestureRecognizer(tapRecognizer3)
    }

    var locationSave:CGPoint = CGPoint.zero

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("     device = \(deviceName), scale = \(UIScreen.main.scale)")

        guard let touch = touches.first else { return }
        locationSave = touch.location(in: self)

        print("gameBoard touchesBegan, location \(locationSave)")
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("                                Unwanted gameBoard touchesEnded!")

        //assert(UIScreen.main.scale == 3.0,"touchEnded is never called unless scale is 3.0")
        //assert(false,"touchEnded should never called")
    }

    @objc func gameboardTapped(_ gesture: UITapGestureRecognizer) {
        print("    GameBoard Tapped Action")
        let location = gesture.location(in: self)
        //assert(location == locationSave, "touch and tap don't agree on location")
    }

    @objc func gameboardDoubleTapped(_ gesture: UITapGestureRecognizer) {
        print("\n    GameBoard Double Tapped Action")

    }

    @objc func gameboardPressed(_ gesture: UITapGestureRecognizer) {
        print("\n    GameBoard Long Press Action")

        if gesture.state == .began {
        } else if gesture.state == .ended {
        }
    }
}

您可以自己测试一下。

我向苹果提交了一份故障报告,并认为我可以在不需要的touchedEnded周围进行编码,直到发现我也丢失了touchedBegan为止。

因此,作为最后的手段,我试图找到并销毁SplitViewController PanGestureRecognizer。我做的第一件事是为SplitViewController创建一个伴随的swift文件,以便我可以检查其view.recognizers等。我将presentWithGesture设置为false,但没有帮助。我设置view.recognizers = nil或[],没有帮助。设置view.gestureRecognizers!.first!.isEnabled = false,没有帮助。

最后,我添加了一个UISplitViewControllerDelegate,它解决了这个问题,但是我只得到了detailViewController,无法导航回到masterViewController。 UISplitViewControllerDelegate中的所有方法都是可选的,因此当我说我创建一个委托时,我的意思是一个空的委托,只需将协议添加到类定义中并设置委托= self即可,它改变了SplitViewController的功能。因此,现在我有了一系列方法的半无限排列,可以使用这些方法来恢复功能,同时仍保持触摸事件。

问题是,是否有人找到解决方法以使触摸事件正常工作?

iPhone XR的左边缘现在对我已经死了。

0 个答案:

没有答案