the structure of my app is following:
UITabBarController -> UINavigationController -> [UIViewController1, UIViewController2, UIViewController3]
What I need to achieve is showing and hiding a child UIViewController just above the tabBar in a small frame, so it is visible over all the controllers in the navigation stack. So when user navigates back and forth the stack, if that child is added it has to be visible over all controllers.
I have tried adding the child to the UITabBarController and it is working fine, the problem I get is that a shadow tabbar item is added to the tabbar, which I do not want.
I have tried adding the child to the navigation controller but that adds other problems when navigating back in the stack, it dismisses the child instead of self and loads the same controller.
Does anyone have a suggestion on how to keep this child controller throughout the whole navigation process.
I have searched for any suggestions here, but none was like my case, so not helpful.
Thank you
I assume you added container view programmatically into you tabbar controller, then you added child view controller into that container view. Am I right?
If this is the case, tabbar controller added the child controller into its viewControllers
array.
You can solve this by calling viewControllers?.removeLast()
right after you've added your child.
This code worked for me:
override func viewDidLoad() {
super.viewDidLoad()
let containerView = UIView()
view.addSubview(containerView)
containerView.translatesAutoresizingMaskIntoConstraints = false
containerView.bottomAnchor.constraint(equalTo: tabBar.topAnchor).isActive = true
containerView.leftAnchor.constraint(equalTo: tabBar.leftAnchor, constant: 40).isActive = true
containerView.rightAnchor.constraint(equalTo: tabBar.rightAnchor, constant: -40).isActive = true
containerView.heightAnchor.constraint(equalToConstant: 150).isActive = true
if let childVC = self.storyboard?.instantiateViewController(withIdentifier: "ChildViewController") {
addChild(childVC)
containerView.addSubview(childVC.view)
childVC.didMove(toParent: self)
childVC.view.translatesAutoresizingMaskIntoConstraints = false
childVC.view.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
childVC.view.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true
childVC.view.rightAnchor.constraint(equalTo: containerView.rightAnchor).isActive = true
childVC.view.leftAnchor.constraint(equalTo: containerView.leftAnchor).isActive = true
if let childIndex = viewControllers?.firstIndex(of: childVC) {
viewControllers?.remove(at: childIndex)
}
}
}
Here, instead of just calling removeLast()
I've checked if the childVC
was actually in that array. Just to be on the safer side.
Adding child view controller to UITablViewConltroller
adds a new tab to the tab bar. and this appears clearly in iOS 13.4
The solution is overriding viewControllers
and return the original controllers only.
/// Neglect child insertion to `viewControllers`
var _viewControllers: [UIViewController]?
override var viewControllers: [UIViewController]? {
get {
return _viewControllers
}
set {
_viewControllers = newValue
}
}
To change tab bar item badge
//This would not work any more
//viewControllers?.last?.tabBarItem.badgeValue = badgeValue
//Use this way instead
tabBar.items?.last?.badgeValue = badgeValue
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With