在 UITabBarControllerDelegate 中获取当前活动 viewController

getting current active viewController in UITabBarControllerDelegate

我想在 UITabBarController 中的所有 viewControllers 上实施 scrollToTop 方法。下面是在UITabBarControllerDelegate的方法和触发器,当我select一个tab的时候。 问题是,当 viewController 处于活动状态时,我只想滚动到 viewController 的顶部。这样用户就可以在不丢失滚动位置的情况下切换标签,但是当他触摸当前活动标签的标签栏中的标签时,它应该滚动到顶部。

func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
    if viewControllerThatIsCurrentlyActiveInTabBar == viewController {
        scrollToTop()
    }
}

基本上,我需要上面 if 语句的那个​​条件。 我试过:viewController.isViewLoadedtabBarController.selectedViewController == viewControllerviewController.isBeingPresented。 None 这些条件有效。它要么不触发 scrollToTop(),要么总是触发,这样您在更改标签时会丢失滚动位置,因为它会立即滚动到顶部。

您需要在 should select 而不是 didselect 中编写代码。因为在 selection 之后无法找到之前的控制器。下面是它的示例代码。

func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
    if tabBarController.selectedViewController == viewController {
        print("Same viewcontroller")
    }
    return true
}

你可以使用下面的扩展来获得 tabbarcontroller 的顶部 viewcontroller。

扩展 UIViewController {

var top: UIViewController? {
    if let controller = self as? UINavigationController {
        return controller.topViewController?.top
    }
    if let controller = self as? UISplitViewController {
        return controller.viewControllers.last?.top
    }
    if let controller = self as? UITabBarController {
        return controller.selectedViewController?.top
    }
    if let controller = presentedViewController {
        return controller.top
    }
    return self
}

}

您可以在下面使用上面的扩展

 if let rootViewController = UIApplication.top() {
    //do with Active view controller
}