简体   繁体   English

touchesBegan 在 iOS 12 中被调用,但在 iOS 13 中不被调用

[英]touchesBegan is called in iOS 12 but is not called in iOS 13

I have a touchesBegan method in my AppDelegate .我的AppDelegate有一个touchesBegan方法。 I use it to detect taps in the status bar.我用它来检测状态栏中的点击。 I've had it there for a long time and it's worked great.我已经在那里使用了很长时间,而且效果很好。 Until the iOS 13 betas came out...直到 iOS 13 测试版出来......

Ever since using iOS 13 touchesBegan has stopped being called.自从使用 iOS 13 以来, touchesBegan就不再被调用了。 Nothing else related to gestures has changed in my app, nothing in my AppDelegate has changed.我的应用程序中与手势相关的任何其他内容都没有改变,我的AppDelegate没有任何改变。 I don't really have much to go on other than touchesBegan is called in iOS 12 and not in iOS 13.除了在 iOS 12 而不是在 iOS 13 中调用touchesBegan之外,我真的没有太多事情要做。

No luck so far though so I'm sharing this here in case someone else has had the same or a similar issue.到目前为止没有运气,所以我在这里分享这个以防其他人遇到相同或类似的问题。


Update: 1 I have found the following issues which are semi related and have lead me to Apple's new UISceneDelegate in iOS 13. None of these issues explain why touchesBegan isn't being called.更新: 1 我发现了以下半相关的问题,并让我在 iOS 13 中找到了 Apple 的新UISceneDelegate 。这些问题都不能解释为什么没有调用touchesBegan And as I understand the UISceneDelegate so far, I haven't yet found why touchesBegan isn't being called.据我了解UISceneDelegate到目前为止,我还没有找到为什么没有调用touchesBegan

View controller responds to app delegate notifications in iOS 12 but not in iOS 13 视图控制器响应 iOS 12 中的应用程序委托通知,但不响应 iOS 13
How to detect touches in status bar 如何检测状态栏中的触摸
iOS13: how to detect a status bar click event? iOS13:如何检测状态栏点击事件?

This is what I am doing, may not be great but only working solution so far.这就是我正在做的,可能不是很好,但目前只是可行的解决方案。 Happy to take improvements.乐于改进。

  • Create TableViewController with contents larger than it's frame.创建内容大于框架的 TableViewController。
  • On view will appear, Scroll to the end of table view.将出现在视图上,滚动到表格视图的末尾。
  • Set TableViewController's frame same as StatusBarFrame and add it to Window's root viewcontroller将 TableViewController 的框架设置为与 StatusBarFrame 相同,并将其添加到 Window 的根视图控制器
  • Inside scrollViewShouldScrollToTop handle ScrollToTop event and scroll to the end to get next events.在 scrollViewShouldScrollToTop 内部处理 ScrollToTop 事件并滚动到末尾以获取下一个事件。
  • On StatusBar frame change, Update TableViewController's frame.在 StatusBar 框架更改时,更新 TableViewController 的框架。

This works works with SceneDelegate as well.这也适用于 SceneDelegate。

ScrollToTopViewController.swift ScrollToTopViewController.swift

class ScrollToTopViewController: UITableViewController {

    private let numberOfRow = 2
    private let cellIdentifier = "empty"

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.allowsSelection = false
        tableView.separatorColor = .clear
        tableView.backgroundColor = .clear
        tableView.showsVerticalScrollIndicator = false
        tableView.showsHorizontalScrollIndicator = false
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellIdentifier)
        view.autoresizingMask = []
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        scrollToBottom()
    }

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return view.frame.size.height
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return numberOfRow
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) ?? UITableViewCell()
        cell.backgroundColor = .clear
        return cell
    }

    override func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool {
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            self.scrollToBottom()
        }
        print("HANDLE SCROLL TO TOP")
        return true
    }

    private func scrollToBottom() {
        tableView.scrollToRow(at: IndexPath(row: numberOfRow - 1, section: 0), at: .bottom, animated: false)
    }
}

AppDelegate.swift or equivalent SceneDelegate functions. AppDelegate.swift 或等效的 SceneDelegate 函数。

private let scrollToTopVC = ScrollToTopViewController()

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    NotificationCenter.default.addObserver(self,
                                           selector: #selector(updateScrollToTopVC),
                                           name: UIApplication.didChangeStatusBarFrameNotification,
                                           object: nil)
    return true
}

func applicationDidBecomeActive(_ application: UIApplication) {
    updateScrollToTopVC()
}

@objc
private func updateScrollToTopVC() {
    guard let viewController = window?.rootViewController else {
        return
    }
    let statusBarFrame: CGRect

    if #available(iOS 13.0, *) {
        statusBarFrame = UIApplication.shared.keyWindow?.windowScene?.statusBarManager?.statusBarFrame ?? .zero
    } else {
        statusBarFrame = UIApplication.shared.statusBarFrame
    }
    scrollToTopVC.view.frame = statusBarFrame
    viewController.addChild(scrollToTopVC)
    viewController.view.addSubview(scrollToTopVC.view)
    scrollToTopVC.didMove(toParent: viewController)
}

I had the same issue recently.我最近遇到了同样的问题。 It took my several hours to figured it out.我花了几个小时才弄明白。 I've created another UIWindow on top of the main window to show app notifications/alerts.我在主窗口顶部创建了另一个 UIWindow 来显示应用程序通知/警报。 For some reason it eats all the touch actions when using ios 13. The workaround of mine is that just disable user interaction on the top one.出于某种原因,它在使用 ios 13 时会吃掉所有的触摸动作。我的解决方法是在顶部禁用用户交互。 But that means you can't do any user interaction with notifications/alerts obviously.但这意味着您显然无法与通知/警报进行任何用户交互。

最近我遇到了同样的问题,尤其是当有一些变换动画时

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM