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

Posted

技术标签:

【中文标题】touchesBegan 在 iOS 12 中被调用,但在 iOS 13 中未被调用【英文标题】:touchesBegan is called in iOS 12 but is not called in iOS 13 【发布时间】:2019-09-05 13:33:45 【问题描述】:

我的AppDelegate 中有一个touchesBegan 方法。我用它来检测状态栏中的点击。我在那里已经有很长时间了,而且效果很好。直到 ios 13 测试版出来......

自从使用 iOS 13 后,touchesBegan 就不再被调用了。我的应用程序中与手势相关的其他任何内容都没有改变,我的AppDelegate 中的任何内容都没有改变。除了在 iOS 12 中而不是在 iOS 13 中调用 touchesBegan 之外,我真的没有太多事情要做。

到目前为止还没有运气,所以我在这里分享这个,以防其他人遇到相同或类似的问题。


更新:1 我发现了以下半相关的问题,并导致我在 iOS 13 中找到了 Apple 的新 UISceneDelegate。这些问题都不能解释为什么没有调用 touchesBegan。到目前为止,据我了解UISceneDelegate,我还没有找到为什么没有调用touchesBegan

View controller responds to app delegate notifications in iOS 12 but not in iOS 13How to detect touches in status bariOS13: how to detect a status bar click event?

【问题讨论】:

你找到什么了吗?遇到同样的问题,一直无法解决。 @Miguel,还没有,但如果我愿意,我会在这里更新。 @Xeaza 感谢您的研究。我有同样的问题,似乎在 iOS 13 上应该在 SceneDelegate 上检测到水龙头,但我认为这意味着应用程序必须放弃对 的支持 【参考方案1】:

这就是我正在做的事情,可能不是很好,但到目前为止只是可行的解决方案。乐于改进。

创建 TableViewController 的内容大于它的框架。 将出现在视图中,滚动到表格视图的末尾。 将 TableViewController 的框架设置为与 StatusBarFrame 相同,并将其添加到 Window 的根视图控制器中 scrollViewShouldScrollToTop 内部处理 ScrollToTop 事件并滚动到末尾以获取下一个事件。 在状态栏框架发生变化时,更新 TableViewController 的框架。

这也适用于 SceneDelegate。

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 或等效的 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)

【讨论】:

【参考方案2】:

我最近遇到了同样的问题。我花了几个小时才弄明白。 我在主窗口顶部创建了另一个 UIWindow 来显示应用通知/警报。由于某种原因,它在使用 ios 13 时会吃掉所有的触摸动作。我的解决方法是禁用顶部的用户交互。但这意味着您显然不能与通知/警报进行任何用户交互。

【讨论】:

以上是关于touchesBegan 在 iOS 12 中被调用,但在 iOS 13 中未被调用的主要内容,如果未能解决你的问题,请参考以下文章

你如何知道在 touchesBegan 中被触摸的对象是啥?

TouchesBegan 在下一个视图控制器中被识别

在 touchesBegan 中删除 SKNode 树

iOS 9.3 touchesBegan/Ended 未在模拟器中触发

touchesBegan 不能在 iOS 中的 UIView 上工作?

IOS 应用程序 ARN 在 AWS SNS 中被禁用,即使 p12 文件的到期日期在明年