un-hiding tabbar ios swift - ios

I'm working with two table view controllers. When a button is pressed on a cell from table view a, table view b comes up on top of a.
In the code for tableview a I wrote that when the button that takes you to table b is pressed self.tabbarcontroller?.tabbar.hidden = true.
That worked for hiding the tabbar but when i put the code in the second table view self.tabbarcontroller?.tabbar.hidden = false the tabbar doesnt come back.
// present view controller
let vieww = self.storyboard?.instantiateViewControllerWithIdentifier("viewTable") as! viewsVC
vieww.view.backgroundColor = .lightGrayColor()
vieww.view.alpha = 0.9
vieww.modalPresentationStyle = .OverCurrentContext
vieww.hidesBottomBarWhenPushed = true
self.presentViewController(vieww, animated: true, completion: nil)
// hide tabbar
self.tabBarController?.tabBar.hidden = true

Add the code
self.tabBarController?.tabBar.hidden = false
to the ViewDidAppear method, rather than the viewDidLoad method in the original tableViewController.
The issue you are encountering is that the view is not loaded after you go back, but rather appears right away since it has already been loaded beforehand.
It should look like this:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
self.tabBarController?.tabBar.hidden = false
}
This should fix the problem.
Good luck with your project!

Related

How to hide UITabBar when going back in UINavigationController

I have three viewControllers:
FeedController (UITabBar is visible)
PostController (UITabBar is hidden)
UserController (UITabBar is visible
I do this with the following code, from FeedController to PostController:
let postVC = PostController()
postVC.hidesBottomBarWhenPushed = true
pushViewController(postVC, animated: true)
postVC.hidesBottomBarWhenPushed = false
Then, from PostVC to UserVC:
let userVC = UserController()
userVC.hidesBottomBarWhenPushed = false
pushViewController(userVC, animated: true)
It works great. It shows the UITabBar everywhere except when navigating to a Post. However, the problem occurs when I go to a User Profile (UserController) from within a Post. It shows the UITabBar on the profile, as intended, but when I navigate back (using the back button in my UINavigationController) the UITabBar is still visible. I want it to be hidden again when I go back from the userVC to the postVC.
Is there any way I can accomplish this?
try in your post viewController:
override func viewWillDisappear(_ animated: Bool) {
postVC.hidesBottomBarWhenPushed = true
}
That will call it when the view is about to disappear but not when it appears so it should hide when you go back.

Transition to Large Title from Small title shows small title for a moment in the destination view controller

I have two view controller in a navigation controller. The root view controller has small title and the next view controller has large title.
When I push the next view controller, I set
self.navigationItem.largeTitleDisplayMode = .always
In the viewDidLoad of next view controller. The problem is, when transitioning it shows the title as small for a moment and then the title becomes big. But I just want to show the big title. I tried setting the title text in ViewDidAppear, it kind of works but the title appears late. I don't want that too.
Say you are doing something like this in vc1
let vc2 = SomeVC()
vc2.navigationItem.largeTitleDisplayMode = .always
self.navigationController.pushViewController(vc2, animated: true)
So try to set the property before pushing the viewcontroller
Had the same issue, I did this :
In VC 1 :
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationItem.largeTitleDisplayMode = .never
}
In VC 2 :
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationItem.largeTitleDisplayMode = .always
navigationController?.navigationBar.prefersLargeTitles = true
}

Setting isUserInteractionEnabled on tabBar doesn't work the first time

If I have a UITabBarController and do this inside one of its view controllers:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
tabBarController?.tabBar.isUserInteractionEnabled = false
}
the first time it shows, I can still change tabs.
If I tap on another tab and tap back on the first tab, then the tabbar is really disabled, but not the first time.
Why? And how do I solve this?
EDIT:
There is one detail I noticed, the tabBarController?.tabBar.isUserInteractionEnabled = false has to be on the second view controller of a navigation controller. In other words:
Say I have that structure
UITabBarController
UINavigationController
UIViewController (1)
UIViewController (2)
UIViewController (3)
So if I add that viewDidAppear code on view controller (2), you can change the tab once, but not the second time (after you navigate to it, obviously).
And there is more, if I go back after navigating to view controller (2), the tab bar becomes "interactable" again, without my setting it to true.
Having a tab bar in view, but not being able to interact with it will probably be confusing and frustrating for the user. And while I don't have the reason or solution for the original question, I have an alternative suggestion:
Hide the tab bar in UIViewController (2):
override func viewDidLoad() {
super.viewDidLoad()
tabBarController?.tabBar.isHidden = true
}
We're putting this in viewDidLoad so it's hidden as soon as the view
appears.
This also requires that you explicitly unhide it in UIViewController (1) for when the user hits the back button. Do it in viewWillAppear since the view was loaded already and we're going back to it.
override func viewWillAppear(_ animated: Bool) {
tabBarController?.tabBar.isHidden = false
}
While I have experienced the same behavior with:
tabBarController?.tabBar.isUserInteractionEnabled = false
..what you CAN do is disable each of the items in the tabBar.items collection, and then re-enable them in the viewWillAppear method of another controller. For example, if you didn't want your users tabbing out of menu #1 once they are inside it, you could do something like this in the subsequent controller(s):
override func viewWillAppear(_ animated: Bool) {
//0th tab items remains enabled as "only choice" for user
self.tabBarController!.tabBar.items![1].isEnabled = false
self.tabBarController!.tabBar.items![2].isEnabled = false
self.tabBarController!.tabBar.items![3].isEnabled = false
self.tabBarController!.tabBar.items![4].isEnabled = false
}
when the user tabs back to first tab (0) (or hits the back button), in that viewController's viewWillAppear method, re-enable the items:
override func viewWillAppear(_ animated: Bool) {
//re-enable tab items
self.tabBarController!.tabBar.items![1].isEnabled = true
self.tabBarController!.tabBar.items![2].isEnabled = true
self.tabBarController!.tabBar.items![3].isEnabled = true
self.tabBarController!.tabBar.items![4].isEnabled = true
}

UISearchController black screen

I have looked at other answers to this problem but they did not solve my problem.
This is my storyboard setup:
In my UITableViewController, if I set self.definesPresentationContext = true then the search bar will appear on every tab. If I don't, then the table will turn black after clicking search then switching to another tab and switching back.
Workaround 1: Dismiss searchController or set isActive to false in viewWillDisappear.
Problem: The search bar gets push down from the top every time I switch back and forth:
Workaround 2: Set searchController.searchBar.isHidden = true.
Problem: In my other tab which also uses UISearchController, it's not able to present the scope due to another search bar being already present (but hidden):
Attempt to present <UISearchController: 0x7ff81ac0aa30> on <xxx.ViewController: 0x7ff81ac0a6f0> which is already presenting (null)
I was having the same problem and was fixed, handling correctly the definesPresentationContext properly, so I just define this property to true in viewDidAppear and set it false in viewWillDisappear
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if(self.searchController == nil)
{
self.setupSearchBar()
}else{
self.definesPresentationContext = true
}
}
override func viewWillDisappear(_ animated: Bool) {
self.searchController!.isActive = false
self.searchController!.searchBar.removeFromSuperview()
self.definesPresentationContext = false
if(self.showingSearchBar)
{
self.rigthNavBarButtonAction()
}
super.viewWillDisappear(animated)
}
I hope this helps you
Using your Workaround 1, setting self.searchController!.isActive = true in viewDidAppear does the magic. You'd also need to restore the search bar text though.

conditional showing of uitoolbar

I have a UIViewController that is presented in two ways, either modally or pushed on top of a navigation controller stack. The UIViewController contains a UITableView and a UIToolbar. When presented modally, i needed a way of showing a title for the ViewController, so I added in another UIToolbar, topToolbar. My problem is, whenever I push the UIViewController, I don't need topToolbar anymore, since the navigation tabbar already shows the title. When I set topToolbar's hidden property to true, however, my UITableView is not bound to the bottom of the navigation tab bar and there's space between the UITableView and the navigation tabbar, which doesn't look so good. I tried to call removeFromSuperview() on topToolbar instead of setting its hidden property to true, but that didn't work out, and topToolbar appeared under the navigation bar, and now i have two titles instead of one. Any idea on how this can be done? I can't add pictures, but here's my code for manipulating the appearance of the UIViewController based on whether it's presented modally or pushed on top of the navigation stack:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
if itemBought != nil {
cart.items.append(itemBought!)
}
totalView.layer.borderColor = UIColor.grayColor().CGColor
totalView.layer.borderWidth = 0.5
totalLabel.text = "$" + String(format: "%.2f", cart.getTotal())
if let navBar = self.navigationController?.navigationBar {
//hide toolbar and tabbar
topToolbar.removeFromSuperview()
self.tabBarController?.tabBar.hidden = true
//hide shop button
var bottomItems: [UIBarButtonItem] = bottomToolbar.items as! [UIBarButtonItem]
if let index = find(bottomItems, shopToolbarButton) {
bottomItems.removeAtIndex(index)
}
bottomToolbar.items = bottomItems
}
}
I should also mention that i have a constraint on the UITableView that's basically: distance between UItableView.top and Top Layout Guide.Bottom is <= to the height of topToolbar, which is 44.
Any ideas?
When you present the View Controller modally, why not put it in a UINavigation Controller?
let navigationController = UINavigationController(rootViewController: myViewControllerInstance)
self.navigationController?.presentViewController(navigationController, animated: true, completion: { () -> Void in
//do something here when animation is complete if you want
})

Resources