2
votes

I have a subclass of UITabBarController declared as follows

class TabbarViewController: UITabBarController, UITabBarControllerDelegate {
    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
        self.currentTabIndex = tabBarController.selectedIndex

        if self.currentTabIndex == 2 {
            let reportVC = UIWindow.getVisibleViewControllerFrom(tabBarController) as? ReportsViewController

            if let reportsViewController = reportVC {
                if reportsViewController.reportTableView.numberOfRows(inSection: 0) > 0 {
                    reportVC?.reportTableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)

                    let navVC = viewController as? UINavigationController
                    let destinationVC = navVC?.viewControllers.last as? ReportsViewController

                    return (destinationVC != nil) ? false : true
                }
            }
        }
        return true
    }

    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
        let newIndex = tabBarController.selectedIndex

        let tabIndexList = [0, 1]

        if self.currentTabIndex == newIndex && tabIndexList.contains(newIndex)  {
            let hbgViewController = (newIndex == 2)
                ? tabBarController.selectedViewController as! UINavigationController
                : tabBarController.selectedViewController as! DLHamburguerNavigationController

            switch newIndex {
            case 0:
                let alertsViewController = hbgViewController.viewControllers[0] as! AlertsViewController
                alertsViewController.alertsTableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
                break
            case 1:
                let newsViewController = hbgViewController.viewControllers[0] as! NewsViewController
                newsViewController.newsTableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
                break
            default:
                break
            }
        }
    }
}

When a user taps on the currently selected tab, the tableview scrolls to the top. This works as expected, however, when the user taps on an item in the table view, a webview is loaded with a remote news article. After the view is dismissed, the above code no longer works, Navigating tabs work, but didSelect and shouldSelect no longer get called. I have no idea why.

Here's how the webview is presented:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let newImageSource = self.newsArticles?[indexPath.row].getImageUrl(type: Article.FireNewsImageType.NewsFeed)

    let articleURLString = self.newsArticles?[indexPath.row].url

    let webViewController = GDWebViewController()
    webViewController.title = self.newsArticles?[indexPath.row].title
    let webVCNav = UINavigationController(rootViewController: webViewController)

    webViewController.showsToolbar = false
    webViewController.progressIndicatorStyle = .both
    webViewController.loadURLWithString(articleURLString!)

    let cancel = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(NewsViewController.dismissVC))
    webViewController.navigationItem.rightBarButtonItem = cancel

    self.present(webVCNav, animated: true, completion: nil)
}

GDWebViewController can be found here if required: https://gist.github.com/elimence/91cf35dfe677b38b23a27c6d54d44285

Any pointers would be appreciated thanks :)

1
Hi, did you set the TabbarViewController's delegate to itself?Zonily Jame
@ZonilyJame damn! thats the reason. I set it in viewDidLoad and unset in viewWillDisappear, but I forget to re-set it in viewWillAppear. I'm super grateful :) If you'll provide an answer, I'll accept it.SamAko

1 Answers

5
votes

It seems like you're not setting the UITabBarController's delegate to your TabbarViewController class

You can either place it on viewDidLoad() or another part of your code like this.

override func viewDidLoad() {
    super.viewDidLoad()

    // this code right here.
    self.delegate = self
}