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