Disable navigation bar transparency while pushViewController - ios

I have TableViewController embed in NavigationController, also I have DetailedViewController that should be opened when cell on in TableViewController is selected.
So I calling
navigationController?.pushViewController(DetailedViewController, animated: true)
My navigation bar settings:
navigationController?.navigationBar.isTranslucent = false
navigationController?.navigationBar.barTintColor = .green
DetailedViewController's navigation bar is hidden
self.navigationController?.isNavigationBarHidden = true
and while I see push animation from TableViewController to DetailedViewController I can see some of content from Controller that stands behind TableViewController though navigation bar that becomes transparent for this transition.
What can I do with it?

This is compilers undefined behaviour, You can achieve your goal with the following operations.
1) Select Navigation controller-> Navigation Bar.
2) Untick the translucent property. (See editor pane).
3) Also hide the the navigation Bar from storyboard.
4) Show the navigation bar in view controller where it is required.
//Code to show navigation bar:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.navigationController?.navigationBar.isHidden = false
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(true)
self.navigationController?.navigationBar.isHidden = true
}

Related

swift how to push back to navigation view control

I have several view controllers and they are very complexed.
MainVC (embed with tab bar controller)
FriendListVC
ChatRoomUpperVC (embed with navigation view controller)
ChatRoomVC (NavigationViewController with embed in ChatRoomUpperVC) (only shows the tab bar)
ChatRoomQuestionVC (pushed from ChatRoomVC) (only shows the navigation bar)
MatchedWaitVC (pushed from ChatRoomQuestionVC) (hide both tab and navigation bars)
ChatVC (pushed from MatchedWaitVC) (only shows the navigation bar)
SettingVC
What I have to do is when I click the back button from the ChatVC, I should back to ChatRoomVC and show the tab bar on the bottom only.
I tried the code below but it shows the black screen and there is no tar bar neither.
override func willMove(toParentViewController parent: UIViewController?) {
if parent == nil
{
var viewControllers = navigationController?.viewControllers
viewControllers?.removeLast(3)
navigationController?.setViewControllers(viewControllers!, animated: true)
self.navigationController?.isNavigationBarHidden = true
self.tabBarController?.tabBar.isHidden = false
}
}
I guess you can use following hack to achieve what you want. In the viewDidLoad method of the ChatVC do:
override func viewDidLoad() {
super.viewDidLoad()
if let root = navigationController?.viewControllers.first {
navigationController?.viewControllers = [root, self]
}
}
This will remove the inbetween view controllers that are between ChatVC and ChatRoomVC. Now popping back (e.g. using the standard back button, or swiping from the left edge of the screen) will jump back directly to the ChatRoomVC.
EDIT
To show the tabBar again in the ChatRoomVC, add this to the viewDidAppear:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.tabBarController?.tabBar.isHidden = false
}
This will ensure that as soon as ChatRoomVC appears on the screen, its tabBar will be presented, too.

how to have the back navigation bar without the navigatin bar

I have a main page, which has a button that will go to another page.
I want when i go the second page, to have a back button at the top left of the navigation bar.
I added a navigation controller to the main view controller, and then i added a push segue to my second view controller (second page), so an automatic back button created.
what i want is that i do NOT want the navigation bar to be in the main view controller, and I don't want it to be in the second view controller, I just want to have the back button in the second view controller.
I thought about it and i came up doing:
self.navigationController?.setNavigationBarHidden(true, animated: false)
in the main view controller, that actually hide the navigation, but that makes the second view ctonroller to loose its back button.
do you have any solution to my problem?
this is the main view controller (which has the navigation bar, but i would like to not have it)
this is the second view controller, which has the back button,
I have no problem if i leave the navigatino bar, if it was transparent, any idea please? (and by transparent, i mean i can see my image bellow it)
Update 1
after the first comment gives me a hint, i tried to applied it like this:
class CustomNavigationBar: UINavigationBar {
override func drawRect(rect: CGRect) {
super.drawRect(rect)
}
}
and I set the class of my navigation bar in the UINavigationControlelr to my custom navigation bar.
and in my main view controlelr i add this:
self.navigationController?.navigationBar.translucent = true;
self.navigationController?.navigationBar.backgroundColor = UIColor.clearColor()
but the result is that my Main view controller, still has a place (though it is empty) for the navigation bar. can't i make this place as transparent to see the image bellow it?
add this to the main view controller
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.Plain, target: nil, action: nil)
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), forBarMetrics: UIBarMetrics.Default)
self.navigationController?.navigationBar.shadowImage = UIImage()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.setNavigationBarHidden(true, animated: true)
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
self.navigationController?.setNavigationBarHidden(false, animated: true)
}

Nav Bar Hidden on View Controller On Second and Subsequent Appearances

I have a parent TableViewController and a child ViewController all within the context of a navigation controller. What I want to happen is for the table view controller to NEVER show the nav bar, and for the view controller to ALWAYS show the nav bar. I hide and show the nav bar within the viewWillAppear func of each subclass, like this:
table view controller:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(true);
navigationController?.navigationBar.hidden = true
UIApplication.sharedApplication().statusBarHidden=true
}
view controller:
override func viewWillAppear(animated: Bool) {
self.navigationController?.navigationBarHidden = false
}
This works for the first navigation. When I launch the app, the parent table view controller hides the nav bar, and when I select the first cell, the child view controller dutifully displays the nav bar. However, when I touch 'Back' on the nav bar, and then select the cell again, the view controller is no longer displaying the nav bar.
Is there a better way to do this?
Update - as requested attaching screenshots of XIB and Storyboard. Note that there is no XIB for the parent TableViewController. I am not confident that these screenshot will provide much insight. Especially that of the storyboard. Unfortunately, Xcode only has 2 zoom levels:
1. Too zoomed in to be useful
2. Too zoomed out to be useful
Nonetheless, here you have them:
That should work fine: When your ViewController will appear, the code should get executed every time. Try with an "print" to test if that happens.
First View Controller
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(true)
print("viewWillLoad - Table View")
self.navigationController?.navigationBarHidden = false
}
Second View Controller
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(true)
print("viewWillLoad - Detail View")
self.navigationController?.navigationBarHidden = true
}
Ill use that in some applications too.

hidesBottomBarWhenPushed not set when returning back to ViewController

I have the hidesBottomBarWhenPushed = true set for one of my UIViewController's (call it ViewControllerA) that is pushed onto my UINavigationController stack. I also opt to show the bottomBar when I push a new ViewController ontop of ViewControllerA. Therefore I have:
class ViewControllerA: UIViewController {
override func viewWillDisappear(animated: Bool) {
self.hidesBottomBarWhenPushed = false
}
override func viewWillAppear(animated: Bool) {
self.hidesBottomBarWhenPushed = true
}
This all works fine.
When I push ViewControllerA, the bottom bar hides.
When I push any other ViewController, the bottom bar shows.
However, when I am traveling backwards in the navigation stack (aka hitting the UIBarButtonItemBack button), I cannot get the bottomBar to hide when I pop the navigation stack to reveal ViewControllerA.
What am I missing? Thanks!
Got it! Here's what worked:
class ViewControllerCustom: UIViewController {
init() {
self.hidesBottomBarWhenPushed = true
}
override func viewDidAppear(animated: Bool) {
self.hidesBottomBarWhenPushed = false
}
}
And then in every UIViewController's custom implementation of BarButtonItemBack pressed I check to see if the previous view controller (that will be popped to needs to hide the tab bar). Granted I abstracted this out into a general function so I didn't need to repeat code, but here's the concept. Thanks for the help figuring this out though!
func barButtonItemBackPressed(button: UIButton) {
var viewControllers = self.navigationController!.viewControllers as! [UIViewController]
if ((viewControllers[viewControllers.count - 2]).isKindOfClass(ViewControllerCustom.self)) {
(viewControllers[viewControllers.count - 2] as! ViewControllerCustom).hidesBottomBarWhenPushed = true
}
self.navigationController?.popViewControllerAnimated(true)
}
I believe the intended use of this property is to hide the bar when pushed. So, when your view controller appears after the top-most one is popped, it wasn't pushed on the stack, so it doesn't change the tab bar's appearance.
This leaves you with two options:
1) Keep the bottom bar for all view controllers. When text is being entered, the keyboard covers the bottom bar.
2) Hide the bottom bar for View Controller A, as well as any other view controller that is pushed on top of A.

Strange view effect when navigating and changing visibility of navigation bar

I have a UINavigationController and I want its root view controller to hide the navigation bar, so I wrote this in the root view controller's class:
override func viewWillLayoutSubviews() {
self.navigationController?.setNavigationBarHidden(true, animated: false)
}
This effectively hides the navigation bar. This root view controller has a button that pushes a new view controller when tapped. I want this second view controller to show the navigation bar, so in its subclass:
override func viewWillLayoutSubviews() {
self.navigationController?.setNavigationBarHidden(false, animated: false)
}
Navigation bar is then shown, but when I tap its back button and I navigate back to the previous view controller (the one I wanted to hide the navigation bar), for an instant at the top of its view it is shown a black space where the navigation bar should be, and finally the view "goes" to the top of the screen again.
How could I avoid this effect?
Try to set the navigation bar hidden in viewWillAppear.
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated);
self.navigationController?.setNavigationBarHidden(true, animated: false)
}

Resources