【问题标题】:UITabBarControllerDelegate on two separate UIViewControllers - Swift两个单独的 UIViewControllers 上的 UITabBarControllerDelegate - Swift
【发布时间】:2017-06-30 13:09:30
【问题描述】:

我有以下代码,我试图在 UIViewcontroller 上实现“滚动到顶部”并在另一个 UIViewController 上实现“滚动到开头”。

第一个 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)
        }
    }
}

当然,它们都连接到同一个 UITabBar。 问题是当我打开应用程序并按下 tabBarIndex 0 时,它会滚动到表格视图的顶部。

然后我更改 VC 并尝试按 tabBarIndex 2,因此它会将我带到集合视图的第一项。

之后我回到第一个 VC,当我尝试按下 tabBarIndex 0 时,tableview 没有滚动到顶部(就像我第一次打开应用程序时所做的那样)。

但是带有集合视图的第二个 VC 工作正常。

知道为什么会发生这种情况吗?

【问题讨论】:

    标签: ios swift uiviewcontroller uitabbarcontroller


    【解决方案1】:

    每次出现 VC 时都不会调用 viewDidLoad,而只会调用一次(或之前释放它时)

    vc 0 的委托只设置了一次...然后 vc1 被加载并设置为委托...但随后不再是 vc0。

    要使其工作,请在 viewWillAppear 中设置委托。

    注意

    为此一遍又一遍地更改代表很奇怪......并且检查索引充其量是脆弱的,最好使用 DonMag 的解决方案。

    【讨论】:

    • 您对viewDidLoad 有意见!它适用于viewDidAppear,但我不确定我是否理解@DonMag 的答案
    【解决方案2】:

    看起来您正在检查 tabBarController 的 .selectedIndex ... 但这是当前显示的标签的索引,而不是您“正在前往”的标签。

    更可能的是,您想使用类似这样的代码:

    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
        }
    
    }
    

    编辑:这是一个简单的例子,使用子类 UITabBarController。

    像往常一样设置故事板,创建视图控制器并将它们连接为“选项卡”,然后将 TabBarController 的自定义类设置为MyTabBarController。此示例代码将(希望)易于理解。

    一个可运行的示例位于: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
            }
    
        }
    
    }
    

    【讨论】:

    • 我应该把它放在哪个视图控制器上?
    • 我已经为此类任务将UITabBarController 子类化...或者,创建一个单独的NSObject, UITabBarControllerDelegate 类并将其分配为委托...选项卡的视图控制器。我建议子类化。
    • 如果我将UITabBarController 子类化,我如何从其他 vcs 访问 tableview 或 collectionview?
    • 子类化似乎很奇怪
    • @Daij-Djan - 与几乎所有事情一样,有不止一种方法可以做到这一点。我永远不会声称“我的方式是最好的方式”——所以我当然愿意听取意见。
    【解决方案3】:

    可能不适用于所有场景,请检查您的VC是否已设置为

    self.tabBarController?.delegate = self
    

    在您的ViewDidLoad()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-01
      • 1970-01-01
      • 2012-06-26
      • 1970-01-01
      • 1970-01-01
      • 2018-07-03
      • 1970-01-01
      相关资源
      最近更新 更多