简体   繁体   English

两个独立的UIViewControllers上的UITabBarControllerDelegate-Swift

[英]UITabBarControllerDelegate on two separate UIViewControllers - Swift

I have the following code that i'm trying to achieve a "scroll to top" on a UIViewcontroller and "scroll to beginning" on another UIViewController. 我有以下代码,我试图在UIViewcontroller上实现“从顶部滚动”,在另一个UIViewController上实现“从开始滚动”。

The first VC has a table view and the second VC has a collection view. 第一个VC具有表视图,第二个VC具有收集视图。

-NearMeViewController-
override func viewDidLoad() {
        super.viewDidLoad()
        self.tabBarController?.delegate = self
        //....
}
extension NearMeViewController: UITabBarControllerDelegate {
    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
        let tabBarIndex = tabBarController.selectedIndex
        if tabBarIndex == 0 {
            self.nearMeTable.setContentOffset(CGPoint.zero, animated: true)
        }
    }
}

-MapSearchViewController-
override func viewDidLoad() {
        super.viewDidLoad()
        self.tabBarController?.delegate = self
        //....
}

extension MapSearchViewController: UITabBarControllerDelegate {
    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
        let tabBarIndex = tabBarController.selectedIndex
        if tabBarIndex == 2 && requests.mapEventData.count > 0 {
            self.resultsCollectionView?.scrollToItem(at: IndexPath(row: 0, section: 0),
                                                     at: .left,
                                                     animated: true)
        }
    }
}

They are both connected to the same UITabBar of course. 它们都连接到相同的UITabBar。 The issue is that when i open the app, and i press the tabBarIndex 0 it scrolls to top of the table view. 问题是,当我打开应用程序并按tabBarIndex 0时,它将滚动到表格视图的顶部。

Then i change VC and i try to press the tabBarIndex 2, so it takes me to the first item of the collection view. 然后,我更改VC,并尝试按tabBarIndex 2,因此将我带到集合视图的第一项。

Afterwards I go back to the first VC and when i try to press the tabBarIndex 0, the tableview is not scrolling to top (as it was doing when i first opened the app). 之后,我回到第一个VC,当我尝试按下tabBarIndex 0时,tableview不会滚动到顶部(就像我第一次打开该应用程序时所做的那样)。

But the second VC with the collection view is working fine. 但是具有集合视图的第二个VC可以正常工作。

Any idea why this might happen? 知道为什么会发生这种情况吗?

It looks like you are checking the tabBarController's .selectedIndex ... but that is the index of the currently showing tab, not the tab you are "on your way to." 看起来您正在检查.selectedIndex.selectedIndex ...,但这是当前显示的选项卡的索引,而不是您“正在访问”的选项卡的索引。

More likely, you want to use code similar to this: 您更可能希望使用与此类似的代码:

func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {

    if let vc = viewController as? MapSearchViewController {
        // user tapped Map Search tab item
    }

    if let vc = viewController as? NearMeViewController {
        // user tapped Near Me tab item
    }

}

Edit: Here is a simple example, using a subClassed UITabBarController. 编辑:这是一个简单的示例,使用子类的UITabBarController。

Set up your storyboard as normal, creating View Controllers and connecting them as "Tabs", then set the Custom Class of the TabBarController to MyTabBarController . 正常设置情节MyTabBarController ,创建视图控制器并将其连接为“制表符”,然后将TabBarController的自定义类设置为MyTabBarController This sample code will (hopefully) be easy to follow. 此示例代码将(希望)易于理解。

A runnable example is at: https://github.com/DonMag/SWTabBarSubclass 一个可运行的示例位于: https : //github.com/DonMag/SWTabBarSubclass

//
//  TabBarSample.swift
//

import UIKit

class FirstViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // all your normal setup stuff....
    }

    func firstViewSpecific(_ aValue: Int) -> Void {
        print("Passed value is:", aValue)
        // do something with the passed value
    }

}

class NearMeViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // all your normal setup stuff....
    }

    func resetMe() -> Void {
        print("resetMe() called in NearMeVC")
        // do whatever you want, such as
        self.nearMeTable.setContentOffset(CGPoint.zero, animated: true)
    }

}

class MapSearchViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // all your normal setup stuff....
    }

    func resetMe() -> Void {
        print("resetMe() called in MapSearchVC")
        // do whatever you want, such as
        if requests.mapEventData.count > 0 {
            self.resultsCollectionView?.scrollToItem(at: IndexPath(row: 0, section: 0),
                                                     at: .left,
                                                     animated: true)
        }
    }

}

class MyTabBarController: UITabBarController, UITabBarControllerDelegate {

    var myValue = 0

    override func viewDidLoad() {
        super.viewDidLoad()

        // make self the UITabBarControllerDelegate
        self.delegate = self
    }

    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {

        if let vc = viewController as? FirstViewController {
            myValue += 1
            vc.firstViewSpecific(myValue)
            return
        }

        if let vc = viewController as? NearMeViewController {
            vc.resetMe()
            return
        }

        if let vc = viewController as? MapSearchViewController {
            vc.resetMe()
            return
        }

    }

}

viewDidLoad is not being called each time the VC appears but only once (or when it was deallocated before) 每次出现VC时,viewDidLoad不会被调用,而只会被调用一次(或之前被释放时)。

the delegate of vc 0 is set only once... and then vc1 is loaded and set as delegate... but then not vc0 again. vc 0的委托仅设置一次...,然后加载vc1并将其设置为委托...,然后再次设置vc0。

to make it work, set the delegate in viewWillAppear. 为了使其工作,请在viewWillAppear中设置委托。

note 注意

changing the delegate over and over for this is weird... and checking the index is fragile at best go with DonMag's solution. 一遍又一遍地更改委托是很奇怪的……而使用DonMag的解决方案充其量只能检查索引是否脆弱。

might not apply to all scenarios, check if your VC has been set to 可能不适用于所有情况,请检查您的VC是否已设置为

self.tabBarController?.delegate = self

within your ViewDidLoad() 在您的ViewDidLoad()

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

相关问题 在两个UIViewControllers之间进行编程转换(Xcode 9,Swift 4) - Programmatically transitioning between two UIViewControllers (Xcode 9, Swift 4) Swift中一个屏幕上的两个UIViewController之间的交互 - Interaction between two UIViewControllers on one screen in Swift 有没有办法在Swift中同时解雇两个uiViewControllers? - is there a way of dismissing two uiViewControllers at the same time in Swift? 如何以及在何处在 Swift 中初始化 UITabBarControllerDelegate? - How and where to initialize UITabBarControllerDelegate in Swift? 带有swift的依赖注入,带有两个UIViewControllers的依赖图,没有公共父级 - Dependency Injection with swift with dependency graph of two UIViewControllers without common parent 使用Swift和Storyboard在两个UIViewController之间传递数据 - Passing data between two UIViewControllers using Swift and Storyboard 多个AVPlayers在单独的UIViewControllers上 - Multiple AVPlayers on Separate UIViewControllers Swift-具有4个UIViewControllers的UIPageViewController - Swift - UIPageViewController with 4 UIViewControllers iOS (Swift) - UIViewControllers 数组 - iOS (Swift) - Array of UIViewControllers DismissViewController解雇两个UIViewControllers - DismissViewController dismissing two UIViewControllers
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM