Reputation: 159
I've been looking at and trying all the solutions others have posted to this problem, but I'm still not getting it.
My use case is very simple. I have a viewController with a button, when that button is pressed I want to navigate to another tab and reload the data including an api call.
When using the button, I navigate to the tab fine, but viewDidAppear is not being called.
If on another tab, and navigate using the tab bar, viewDidAppear works fine. Also viewWillAppear is working, but I have to add a manual delay to the functions I want to call so it's not ideal.
So what do I need to do to navigate using self.tabBarController.selectedIndex = 0 and get the functionality of viewDidAppear?
Update: The viewWillAppear method I added gets called but I have to add a delay to my functions in order for them to work, and it's a bit clunky, not ideal. Not sure why viewDidAppear will not work :(
Here is a screenshot of the structure:
I appreciate any help on this one!
The "current" ViewController is my tab index 2:
import UIKit
class PostPreviewVC: UIViewController {
//Here I create a post object and post it to the timeline with the below button
@IBAction func postButtonPressed(_ sender: Any) {
//create the post via Firebase api
self.tabBarController?.selectedIndex = 0
}
}
In my destination viewController:
import UIKit
import Firebase
import SDWebImage
import AVFoundation
class HomeVC: UIViewController {
// MARK: - PROPERTIES
var posts = [Post]()
let refreshControl = UIRefreshControl()
//more properties...
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
configureTableView()
reloadTimeline()
UserFirebase.timeline { (posts) in
self.posts = posts
self.tableView.reloadData()
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print("viewDidAppear")
_ = self.view
setupUI()
configureTableView()
reloadTimeline()
UserFirebase.timeline { (posts) in
self.posts = posts
self.tableView.reloadData()
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print("viewWillAppear")
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.reloadTimeline()
self.configureTableView()
}
}
//All the tableview code below here...
}
Added a custom class for my tab bar controller:
import UIKit
class TabBarController: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print("viewDidAppear in tabBar custom Class called")
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print("viewWillAppear in tabBar custom Class called")
}
}
Upvotes: 2
Views: 1769
Reputation: 2859
For UITabBarController
viewDidLoad
only gets called once. and your viewWillAppear
and viewDidAppear
get called multiple times. you can either check if your viewWillAppear
gets called or not. because your view will appear gets called before your viewDidAppear
it's just like going through the reverse engineering process.
You can also add viewDidAppear
method into your UITabBarController
custom class. and call its superclass method into it in that way I think it will solve your problem.
Note: In the case of
UITabbarController
, Always do your UI update task and API calling a task in eitherviewWillAppear
orviewDidAppear
Upvotes: 2
Reputation: 9540
When you are using UITabBarController
, the method viewDidLoad
will called only once when any UIViewController
is loaded in memory. After that, when you are navigating the same UIViewController
, then it will load from memory.
In order to overcome this problem, you must divide your code in viewDidLoad
& viewDidAppear
. So, in viewDidLoad
, you only put that code which you want to intialize once throughout the app such as adding UIView
's or other things, while in viewDidAppear
/ viewWillAppear
, you can make API calls or some functions which fetches dynamic data.
Finally, when you are calling self.tabBarController.selectedIndex = 0
, it will call viewDidLoad
only once and viewDidAppear
/ viewWillAppear
every time when you are navigating that UIViewController
.
Hope this helps to understand like how UITabBarController
works.
Upvotes: 4