I am trying to hide the tab bar during the push to UserProfileViewController from a viewcontroller that has tabBar underneath.
code:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let toVC = UIStoryboard(name:"UserProfile", bundle:nil).instantiateViewController(withIdentifier: "userProfileVC") as? ProfileViewController else { return }
...
toVC.hidesBottomBarWhenPushed = true
self.navigationController?.pushViewController(toVC, animated: true)
}
so the code works fine and it does hide the bottom bar on push. However, right after the push, it gives me a slight delay and shows a blank white space underneath because of the hidden tab bar for like a second or two. I want to get rid of the bottom white space on push. Please help.
I have already tried:
ticking Hide Bottom Bar On Push in storyboard
ticking Under Opaque Bars On Push in storyboard
Layouts & Extend Edges options ticked in storyboard:
Adjust Scroll View Insets
Hides Bottom Bar On Push
Under Top Bars
Under Bottom Bars
Under Opaque Bars
Related
I want the green view to move forward from the container view as follows.
However, when I add a tab bar controller, the green view is cut off as follows.
I tried the following codes so that the green view is not cut off. But it did not work.
containerView.clipsToBounds = false
containerView.layer.zPosition = 100
self.view.bringSubview(toFront: containerView)
The problem seems to be not in the container view. Because when tab bar controller was added, green view started to be cut off.
When I add a tab bar controller, how can I prevent the green view from being cut off?
The problem is that UITransitionView in your UITabBarController clips all subviews. You can fix this easily if you remove clipsSubview from every subview in your TabBarController. I make this with custom TabBarController. Here is my code
class CustomTabBarViewController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
for item in self.view.subviews{
item.clipsToBounds = false
}
self.view.clipsToBounds = false
}
}
Problem
A navigation bar animates as it hides on scroll (hidesBarsOnSwipe). If there is a table on the page with a section header, the section header will stick to the top of the view and follow the user as they scroll. When using these two together, there is a gap between the section header and the navigation bar when the navigation bar is hiding, showing the background table cells. I would expect the section header to follow the navigation bar as it hides without a gap.
Using a section header is not strictly necessary for my issue. I'd simply like a bar that sticks to the top of the screen and follows the user as they scroll.
I've tried alternative approaches to the example posted below, which uses a UITableViewController. Adjusting the insets causes the section header to slip under the status bar. Using a UIViewController containing a static UIView (for the section header) and UITableView causes the same issue.
What would be an appropriate solution for this issue?
Example
The status bar's background is gray and the section header's background is red to better highlight the gap between the navigation bar and the section header. As the table is slowly scrolled down, the yellow table cells peeking through the gap become apparent. After the navigation bar is hidden, the section header resets on the status bar as expected.
View controller used for the above animation:
class TableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Color status bar background.
let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as! UIView
if statusBar.responds(to: #selector(setter: UIView.backgroundColor)) {
statusBar.backgroundColor = .lightGray
}
UIApplication.shared.statusBarStyle = .default
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 20
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let view = UIView()
view.backgroundColor = .red
return view
}
}
Update 1
Removing the background color from the status bar does not resolve the issue I am seeing. The GIF below shows the behavior with the status bar in its original, transparent state.
TLYShyNavBar has a GIF of the behavior I’d like to implement (added below). This project is not maintained and does not work without additional manipulation but has a good example of what I would expect the behavior to look like.
Update 2
I’m understanding that this behavior is not an error/issue but as Apple prefers it. Coloring the background of the View is an option (see answer below). There are two ways to go about that for this situation:
Color the background to match the navigation bar and remove the navigation bar’s shadow to make the view seamless.
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.isTranslucent = false
Color the background to match the red bar.
Unfortunately, this method masks the gap instead of removing it. It makes one of the bars appear to distort in shape during their animation until they've completed their transition in both cases.
The problem is that a table view does not work well fullscreen when there is a status bar, because the cells come up behind the status bar but the section headers do not. So don't do that.
To use a table view controller to work without a navigation bar but with the status bar showing, configure the table view controller as an embedded (custom child) view controller so that you are in charge of the table view's position. Pin the table view top to the safe area top.
That gives the configuration you are after:
The status bar is clear, and the parent view controller's view is visible behind it. The table view itself, along with its section headers and cells, stops at the bottom of the status bar; the cells do not come up behind the status bar. Thus we don't get the mismatch seen in your illustrations.
Here's a gif showing that the result is coherent:
I've colored the nav bar and the main view differently so you can distinguish them, but imagine they were exactly the same color — then this would be totally coherent.
I am hiding my navigation bar when I scroll by calling: self.navigationController?.setNavigationBarHidden(true, animated: true)
The only problem is that the navbar doesnt get hidden all the way.
Whats even stranger is if I push to a new VC and go back and now try to scroll the navigation bar gets hidden all the way which is what I want.
If it matters I am hiding the navigation bar on VC2 then showing it when I exit back to VC 1.
This is what it looks when I try to hide the navbar first time, it doesnt go up all the way/underlying view showing too much.
If I push the to next VC and go back and now try to hide the navigationbar it works
The my view has a constraint of 0 to top layout so its hugging the top
So how can I make my view always be like in the second image when hiding my navigation bar?
Try this code...
Note: This is a simple approach for your problem. If you want more custom look navBar and status bar look .You should read my previous comment...
Set navigation controller property hidesBarsOnSwipe to true
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
navigationController?.hidesBarsOnSwipe = true
}
I understand your question.
The green part in your second image is not a navigation bar, it is a status bar.
You can hide the status bar as below.
You should implement prefersStatusBarHidden on your view controller(s):
In Swift 2:
override func prefersStatusBarHidden() -> Bool {
return true
}
In Swift 3:
override var prefersStatusBarHidden: Bool {
return true
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let memeShowViewController = self.storyboard!.instantiateViewControllerWithIdentifier("ShowMeme") as! MemeShowViewController
memeShowViewController.memeImage = appDelegate.memes[indexPath.row].memeImage
self.navigationController!.presentViewController(memeShowViewController, animated: true, completion: nil)
}
So I have a tableview that has a nav controller embedded in it and when I present the memeShowViewController modally I was wondering why the view of the memeShowViewController has a black background color when I didn't change it to be black.
In storyboard:
In simulator
Right now I'm just adding a navigation bar to the segue-ed view controller, I was wondering if there is a better way to do as the only functionality I need from the navigation bar is for the done button to segue back to the tableView.
The background window has a black background so if your app doesn't cover any part of the window (or alpha = 0) you'll see that black background.
When you drag a UINavigationController into a storyboard, you can enable the Hide Bars On Tap option which will hide/show the navigation bar and toolbar upon tapping anywhere in the UIView. This works well except in the case where you don't have a navigation bar and you only have a toolbar. (You checked Shows Toolbar but not Shows Navigation Bar.) When you launch the app there is no visible navigation bar but when you tap a navigation bar slides down from the top, then if you tap again both bars slide away.
How can you use Hide Bars On Tap with only a toolbar and prevent a navigation bar from appearing?
You can get hold of the gesture recognizer via the barHideOnTapGestureRecognizer property.Then you add actions to this gestureRecognizer to do whatever you want.
In your case ,this snippet will work:`
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.hidesBarsOnTap = true
navigationController?.barHideOnTapGestureRecognizer.addTarget(self, action: "tap:")}
func tap(gest: UIGestureRecognizer){
navigationController?.navigationBar.hidden = true
}