Navigation and Tab bar disappear with Push Segue - swift

I'm developing a swift app that has a Tab Bar Controller and one of the tabs has a Navigation Controller. The tab with a Navigation Controller has a Table View, and the cells in the Table View segue to a regular View Controller. The information appears in the destination view controller as desired, put when the destination view controller is presented, both the tab bar and the navigation bar disappear.
Here is my prepareForSegue:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "entryCellToEntryView" {
if let destination = segue.destinationViewController as? EntryDetailViewController {
if let index = customTableView.indexPathForSelectedRow {
if let cell = customTableView.cellForRowAtIndexPath(index) as? EntryTableViewCell {
destination.entryToDisplay = cell.entry
} else {
print("prepareForSeque: Unable to cast cell as EntryTableViewCell")
}
} else {
print("prepareForSeque: Index cannot be established")
}
} else {
print("prepareForSeque: Destination cannot be downcast to EntryDetailViewController")
}
}
}
Here is a link to a photo of my storyboard:
http://grantbroadwater.com/storyboard.png

The navigation bar and tab bar disappears, because you are using model segue.
Change segue to push are show.
In model segue destination ViewController appears on the top of current viewController.
So destination view controller does not have any idea about your navigation stack or tab bar.
If you use push segue, or show segue now a days, then only it will be pushed into navigation stack.

Related

Switch tab bar controller view controller after dismissing a modally presented view controller

In my project you can create a post from a modal view.
When the modal view is dismissed (user presses on save post) I want to switch the tab bar controller to the second tab (post feed screen).
This topic is similar to my problem. The only difference being this is presented from a modal view. I can't figure out how to implement it in my code (tab bar is nil)
Switch tab bar programmatically in Swift
I have added 3 images to make this issue clearer
code screenshot
console message
#objc func saveAction(sender: UIButton) {
print ("> save pressed")
print(presentingViewController?.tabBarController)
print(presentingViewController)
presentingViewController?.tabBarController?.selectedIndex = 1
dismiss(animated: true)
}
edit: sorry stack overflow doesn't allow me to add images yet
You can do this using delegate pattern. But if you prefer not to add a delegate for this, you can do as shown below;
You can switch the tabbar by changing the selectedIndex property of tabBarController
if let presenter = presentingViewController as? LibraryViewController {
presenter.tabBarController?.selectedIndex = 1
}
dismiss(animated: true)
If you are presenting the modal on navigation controller in tabbar, use:
if let tabBar = presentingViewController as? UITabBarController {
tabBar.selectedIndex = 1
}
dismiss(animated: true)

Segue removes tabBarItem.badgeValue

I have a custom TabBarControllerand on one of the Tab Bar Items I have a round red counter. The first Tab Tab Item presents a summary View Controller. The second Tab Bar Item presents a menu embedded in a Navigation Controller The Tab Bar Counterworks fine across the board, except when I segue back from the summary View Controller. Then the counter disappears. I have tried to load the counter in the customTabBarController:
import UIKit
class CustomTabBarController: UITabBarController {
override func viewDidAppear(_ animated: Bool) {
if tabBarCounter != 0
{
let vc = self.tabBarController?.viewControllers?.last
vc?.tabBarItem.badgeValue = "\(tabBarCounter)"
vc?.tabBarItem.badgeColor = UIColor.red
}
}
}
Screendump of storyboard. (The bottom ViewController is the one I´m having trouble with. Segue highlited)

Navigation controller to view controller that is not initial view controller

Is it possible to add navigation contoller and tab bar to view controller that is not initial view controller?
My “Initial view controller” is Login screen. There’s no need for navigation controller and tab bar.
Navigation controller and tab bar wont appear when i just add them from “Editor -> Embed in -> … “
When Login is successful, then I use this code:
if let viewController = self.storyboard?.instantiateViewController(withIdentifier: "mainView") {
UIApplication.shared.keyWindow?.rootViewController = viewController
self.dismiss(animated: true, completion: nil)
}
I use Xcode 9 and swift 4.
Thank you!
I think you may be looking at this wrong. Always having the login view as the root controller in the view hierarchy, even when not needed would be bad practice. And the LoginController should not own a MainController, but the MainController should own a LoginController. You should make your main view (with the nav controller/tab controller) your root view, and in the viewWillAppear method simply check if the user is authenticated; push the login controller modally if the user is not authenticated. That way your view hierarchy is a bit less complex.
You could have a provider class CurrentUser
class CurrentUser {
var user: User? {
guard let userData = UserDefaults.standard.object(forKey: "user") as? Data,
let user = NSKeyedUnarchiver.unarchiveObject(with: userData) as? User else {
return nil
}
return user
}
static let shared = CurrentUser()
}
And in MainController.viewWillAppear
override func viewWillAppear() {
super.viewWillAppear()
guard let user = CurrentUser.shared.user else {
pushViewController(LoginController(), animated: true)
}
// do additional setup
}
Just my $0.02.
Just to answer your question, not only is it possible but it is common. You can put a navigation controller wherever you want. All that the navigation controller does is create a starting point for the progression of view controllers that are to follow by keeping that history of view controllers alive and in order. Therefore, if you had an app with 3 distinct sections, you may most likely want to put a navigation controller in each section so that the user would be able to drill down into each section independently.

how hide tap bar on another controller before show everything else

I have a simple tap bar example. And for my next view i have a ViewController with tableView and on bottom textInput. when i want hide tap bar i have a code:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject? {
if segue.identifier == "showMe" {
(segue.destinationViewController as! MyViewController)
destinationController.hidesBottomBarWhenPushed = true
}
}
and on my next view when i tap a row on tableView i see first rendering tap bar and then tap bar is hidden and on last input Edit goes down :( how hide this tap bar before show next screen ?
This isn't exactly the best solution, but its a workaround:
set destinationController.hidesBottomBarWhenPushed = false
set contraints properly in your view controller (as if there is no tab bar)
use the following code (as shown) in the view controller where you want to hide the tab bar:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.tabBarController?.tabBar.frame = CGRectZero
self.tabBarController?.tabBar.userInteractionEnabled = false
}
This will make sure that the tab bar is hidden. Now the Autolayout constraints will make sure your view displays correctly with the tab bar height as zero.

Swift: Force show Navigation Bar in Modal

I have the following Storyboard Segue in my Swift project:
The animation is correct, but there is no navigation bar in the destination view controller. I want to force the destination view controller to have a navigation bar. I tried in the destination view controller:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(true)
navigationController?.navigationBar.hidden = false
}
Or:
override func viewWillAppear(animated: Bool) {
self.navigationController?.setNavigationBarHidden(false, animated: true)
}
But it refuses to show any navigation bar.
How can I perform a vertical segue (like "Cover Vertical") but still display a translucent Navigation bar in the destination view controller?
Edit: My Attributes inspector for the destination view controller:
Try to create the Segue to a Navigation controller instead of your view controller. Navigation bars are only shown for view controllers in a navigation stack. In your case, the source view controller seems to be in a navigation stack but not the presented view controller. Try something like this: