检测当第一个触发 popToRootViewController 时第二次点击标签栏项目



我想在用户点击标签栏中的标签栏项目时实现滚动到视图控制器的顶部。我通过在UITabBarControllerDelegate中覆盖tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool方法来做到这一点。

func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
// Scroll to top only if we are already on given tab
if viewControllers?.firstIndex(of: viewController) == selectedIndex {
// Checks if root VC of navigation controller is currently shown and then scrolls it to top
scrollToTop(at: selectedIndex)
}
return true
}

每个选项卡都有导航控制器作为其视图控制器,点击选项卡栏会导致弹出根视图控制器。这很好,但我希望双击工作,即用户在导航控制器中的第二个(或以后)视图中,双击选项卡栏,然后导航控制器弹出,根视图控制器滚动到顶部(第一次点击弹出到根视图控制器,第二个滚动到顶部)。

遗憾的是,当这种情况发生时,仅调用一次此委托方法。只有在弹出过渡结束后,它才会开始检测选项卡栏项上的下一次点击。 切换选项卡时双击工作正常,即用户在选项卡 B 上,双击选项卡 A,然后第一次点击切换到选项卡 A,第二次滚动使其滚动到顶部。

我检查了Facebook和Twitter应用程序,它们都正确处理了快速双击 - 它们弹出然后滚动到顶部。

有没有办法在弹出过渡过程中检测标签栏项目点击?我尝试覆盖UITabBarControllertabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem)但在上述情况下,双击也没有调用两次。添加自定义双击识别器也无济于事,因为它会显着延迟单击选项卡栏,从而导致应用程序看起来滞后。

在这种情况下,您可以尝试使用通知。 首先,为您的 Notification.Name 创建扩展:

extension Notification.Name {
static var userDoubleTapTabbar: Notification.Name {
return .init(rawValue: "User.DoubleTapTabbar")
}
} 

然后,在标签栏控制器中,检测用户双击项目事件并触发通知:

public var lastTabbarItem: UITabBarItem?
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
SEManager.shared.playSound(type: .tap_bottom_tap)
if self.lastTabbarItem == item {
NotificationCenter.default.post(name: .userDoubleTapTabbar, object: nil)
}
self.lastTabbarItem = item
}

然后在 Tabbar 项目视图控制器中,您可以为该通知添加观察者和处理程序,以将表视图滚动到顶部。您可以使用它来检查该选项卡栏项目视图控制器当前是否可见:

if viewController.viewIfLoaded?.window != nil {
// viewController is visible
}

希望它有帮助,对不起我的英语不好。

最新更新