1

I am trying to build a social media app in swift that has a tab bar with 4 icons each connected to a view controller. I want to have the four collection views (that are each associated with a view controller) scroll back to the top when the respective tab bar icon is pressed (Exactly like twitter).

I have the logic for how I want the collection view to come back to the top only if the past tab bar icon was for that respective collection view (this is so that it doesn't just automatically scroll to the top when clicking on the respective tab but needs to be pressed again) I tried to debug my first switch case but have had no luck so I do not have the full code for the other cases yet. What I try to do is reference the correct storyboard, then the correct view controller (in this case homeViewController), and finally call that respective collection view and use setContentOffset to bring it to the top.

Below I provide my whole tabBarController class.

import Foundation
import UIKit

class MainTabController: UITabBarController, UITabBarControllerDelegate {

    var pastTabBar: Int = 0

    override func viewDidLoad() {
        super.viewDidLoad()

        self.delegate = self


    }


    override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {

            let tabBarIndex = tabBar.items?.index(of: item)

            if tabBarIndex == pastTabBar {

                switch tabBarIndex {

                case 0:
                    print ("go to top of home")
                    //updateHomeCollection = 1
                    let HomeSB : UIStoryboard = UIStoryboard(name: "Home", bundle: nil)
                    let HomeVC = HomeSB.instantiateViewController(withIdentifier: "Home") as? HomeViewController
                    HomeVC?.collectionView.setContentOffset(CGPoint(x: 0, y: 0), animated: true)
                case 1:
                    print ("go to top of search")
                case 2:
                    print ("go to top of notifications")

                case 3:
                    print ("go to top of profile")

                default:
                    print ("not working")
                }
            }

        if let tabBarIndex = tabBarIndex {
            pastTabBar = tabBarIndex
        }

        }

}

It keeps signal aborting when I click the home tab! It is printing this exact statement:

Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value

on this line of code:

HomeVC?.collectionView.setContentOffset(CGPoint(x: 0, y: 0), animated: true)
vezunchik
  • 3,669
  • 3
  • 16
  • 25
Matteo
  • 47
  • 9
  • 1
    `HomeSB.instantiateViewController(withIdentifier: "Home") as? HomeViewController` you are instantiating new `HomeViewController` everytime. Hope this helps [UITabBar Programatically](https://stackoverflow.com/questions/26850411/how-add-tabs-programmatically-in-uitabbarcontroller-with-swift) – prex Jun 15 '19 at 03:59
  • I tried making sense of the resource you provided but I think it's too far from my issue. I went ahead and took out the instantiate line and put HomeViewController() instead of HomeVC but still get the same error – Matteo Jun 15 '19 at 04:45
  • And I should've mentioned this but all my viewcontrollers and tab bar controller are done with the storyboard. @prex – Matteo Jun 15 '19 at 04:48

1 Answers1

1

Loading ViewController is not best way. You have to fetch your desired ViewController from Navigation like below

extension HomeTabVC: UITabBarControllerDelegate {

    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
        if previousController == viewController {
            if let nav = viewController as? UINavigationController, let vc = nav.viewControllers[0] as? FeaturedVC {
                if vc.isViewLoaded && (vc.view.window != nil) {
                    let visibleIndex = vc.collectionFeatured.indexPathsForVisibleItems
                    if visibleIndex.count != 0 {
                        vc.collectionFeatured.scrollToItem(at: IndexPath (item: 0, section: 0), at: .bottom, animated: true)
                    }
                }
            }else if let nav = viewController as? UINavigationController, let vc = nav.viewControllers[0] as? CategoryVC {
                if vc.isViewLoaded && (vc.view.window != nil) {
                    let visibleIndex = vc.collectionViewCategory.indexPathsForVisibleItems
                    if visibleIndex.count != 0 {
                        vc.collectionViewCategory.scrollToItem(at: IndexPath (item: 0, section: 0), at: .bottom, animated: true)
                    }
                }
            }else{

            }
        }

        previousController = viewController

    }
}

You have to store Selected ViewController in variable so when you change ViewController from one tab to another it will just change ViewController and when you tap same tab again it will scroll you back to top. This is how iOS is doing it self in all there application

PinkeshGjr
  • 8,460
  • 5
  • 41
  • 56
  • sorry are you telling me I should paste this whole extension in my tabController file? @PinkeshGjr – Matteo Jun 15 '19 at 05:10
  • No you have to change code. You have to added your viewControllers – PinkeshGjr Jun 15 '19 at 05:16
  • Ok thank you, What does CategoryVC variable represent? @PinkeshGjr – Matteo Jun 15 '19 at 05:39
  • ViewController. It's should be your ViewController where you want to scroll. – PinkeshGjr Jun 15 '19 at 05:46
  • I keep getting the error: "Use of undeclared type" for FeaturedVC and CategoryVC, even when I set it to my homeVC. What should I do about that? @PinkeshGjr – Matteo Jun 15 '19 at 05:51
  • I have just shred logic now i can't code for you so try changing with your viewController. – PinkeshGjr Jun 15 '19 at 05:53
  • I got it to work, but I still am wondering.. If featuredVC is the VC I want to present, then what is CategoryVC? Is it supposed to be the same? @PinkeshGjr – Matteo Jun 15 '19 at 06:14
  • I have 2 ViewController in Tab so it's depend on your functionality. If you have 4 tab then there should be more condition – PinkeshGjr Jun 15 '19 at 06:16