How to implement both UIViewController stack behaviour - swift

I noticed that WhatsApp has a somewhat neat navigation behaviour on their iOS app. See the following:
There are two navigation stack behaviour here:
UINavigationController as a child of UITabBarController
UITabBarController as a child of UINavigationController
How to achieve both of this at the same time, just like WhatsApp? Does it uses a custom UINavigationController?
Currently my implementation only does number 2 and not number 1. I do know that to do number 1 I have to make the UINavigationController as a child of UITabBarController, but I will lose number 2.
However if I implemented both, I will get weird result where I get two navigation bar, like:

In the example you give, it looks like they have a UITabBarController as the root view controller. Settings is a view controller inside a navigation controller.
When you tap Data & Storage, it pushes another view controller on to the Settings nav controller's stack.
When you press Help it does the same - but the tab bar is hidden when the Help view controller is pushed on the stack.
See hide / show tab bar when push / back. swift for some ways to do this

Related

Show UITabBar on UIViewControllers that are not part of the UITabBar?

I have an iOS app written in Swift with UITabBarController with 5 UIViewControllers. Now, I have a bunch of UIViewControllers that are not part of the UITabBarController. I'd like to be able to show that same tabbar but I have no idea how to do that. Any clue?
More details: This is one of the View Controllers that the tabbar has. I use storyboard references and split my view controllers into separate more manageable storyboards.
So, the big picture:
There's no initial ViewController since I use storyboardId to get to the initial Navigation Controller. From there we have a ViewController embedded in the same Navigation controller. In that ViewController, there are 2 Container views - one of the size of the bottom ViewController that contains the "hamburger" button that toggles the other Container View which has an embedded UITableView in. When a specific cell is selected it should go to Profile ViewController that's not even in the same storyboard. The segue is set to be Push. Either way, doesn't show the UITabBar on the Profile ViewController
how you doing?
I don't know if I understood, but you are trying to show tabbar after going to another screen, right? If the answer is 'yes', try to change your segue to show(e.g. push).
-----Edit-----
You can do with two ways:
Presenting Modally -> using Current Context
Use push(e.g.) with a navigation view controller, you can also hide the navigation bar if you go to Navigation controller -> Attributes inspector -> Navigation Controller -> Uncheck Shows Navigation Bar
Hope now it works!
Best regards

How to structure controllers using swift?

I want to build an app using swift with the following structure:
Login/Signup screen
Home screen with slide out menu on the left
Different Pages in the menu -> same level like home screen
![Picture of the structure][1]
// Sorry not enough reputation for posting images
Here is an example, but I don't understand it.
GitHub-Link
![Picture of the controller structure][2]
Why is the Login-Screen the rootViewController of the Navigation Controller?
Why is there no "back" button on the other controllers of the menu (Friends, Profile)?
I could remove the segue from Login to Profil and the app still works fine...it's a normal push segue. I don't understand what that sequel does.
I thought every controller which is not the rootviewcontroller of the navigation controller gets pushed on the stack and a "back" button...
Should i split the Login and the Signup screen into two different controllers?
My suggestion:
1. Login screen/Signupscreen
=> Modal segue to navigation controller
2. Navigation Controller => RootViewController: Page 1
But how should I implement the Page 2, Page 3,... at the same hierarchical level as Page 1
How would you structure the controllers?
[1]: http:// i.imgur.com/qHMy6zs.png
[2]: http:// i.imgur.com/wdOGCGa.png
Looking forward to your answers!
Jan
Why is the Login-Screen the rootViewController of the Navigation Controller?
It does not have to be, it's a design decision, personally I would not do it that way.
Why is there now "back" button on the other controllers of the menu (Friends, Profile)?
Pushing a view controller onto a UINavigationController will do this automatically unless you specify that the back button should not be present in the view controller that gets pushed. UIViewControllers have a property called UINavigationItem where you can set the back button to hidden. See here.
I thought every controller which is not the rootviewcontroller of the navigation controller gets pushed on the stack and a "back" button...
Yes that's right, you sort of just answered one of your previous questions.
Should i split the Login and the Signup screen into two different controllers?
Yes that would generally be a good idea. Have a separate view and view controller for each of them. It does depend on your ui design also.
How would you structure the controllers?
It appears you have multiple menus and different sections to your app. In that case using a UITabBarController combined with multiple UINavigationControllers (one navigation controller per tab) may be one way to go about it, I've used this technique before and it works well.
If I a mistaken based on your images and you actually just have one main menu then stick to just one UINavigationController and just push and pop view controllers, have one view controller / view per view/page of your app.
Best thing is to read up about UINavigationController and UITabBarController and decide what suits how you want to layout your views / your design.

Unhide tabbar when a new view is pushed

I have UITableViewController embeded in a UINavigationController in my app. When a row is selected it pushes a UITabBarController. So far so good. The problem is that some of the tabs I push more views but the tab bar gets hiden. I've tried setting hidesBottomBarWhenPushed = NO, but it doesn't work.
I'm using XCode 4 with storyboard
Any ideas?
I've had this problem in one of my apps (though it was in iOS 4.x, using nibs not storyboard).
What I did to solve it: You want to have the root controller for each tab (the one with tabitem, etc) be a navigation controller - and when you push new views onto this navstack, they will respect the top navigation bar and bottom tab bar (they may actually display two navbars, so you have to be careful, but generally this is the way to go.)
first of all you might want to take a look at this
viewController: The view controller that is pushed onto the stack. It
cannot be an instance of tab bar controller.
so pushing an instance of tab bar controller is not recommended. There's a good reference there that might accomplish the task you wanted ill just provide the link here

UITabBarControllers and UINavigationControllers

Problem
I have an app with a UITabBarController and four different tabs. Three of these tabs are tables which you can click on each row and it would take you to another view.
Question
How would I implement that in terms of navigation? Should I create a UITabBarController with Navigation Controllers as tabs (as shown in image 1) or with View Controllers as tabs (as shown in image 2) with each View Controller having its own Navigation Controller property?
Image 1:
Image 2:
I tried both but its not working well and its confusing. I'd like to know which is more appropriate so I can focus on that method and then see why it's not working.
The first method you propose is the only method. View controllers have a navigationController property, but it will only return something if your view controller is currently contained within a parent navigation controller.
So to be clear: you should have a UITabBarController which contains your navigation controllers, one navigation controller for each tab that you want to have a navigation hierarchy in.

One UINavigationcontroller for the whole app?

i´ve created a UINavigationController in my appdelegate and initialized it with my "modelselectionViewController". This VC has different uibuttons and when touched, a new VC ("modelViewController") is pushed on the navigationstack.
This "modelViewController" acts as my template view and has a uitabbarcontroller with different tabs. The first VC is shown immediately but any changes on the navigationcontroller doesn´t work. I would like to set the name of the title but that navigationcontroller is null.
NSLog(#"navi: %#",
self.navigationController);
If i change my code to push the different VC when touching the different tabs, navigation works but only with a third level of navigation hierachy.
I want to know if it´s possible to use only one navigationcontroller for all my different tabs. Hope i made my setup clear. Appreciate all your help. thanks
I think you might want to read Combining ViewControllers.
In general, you should have the tabbar controller as a 'root' controller, not as a 'child' controller. A quick search in Apple's doc didn't yield a formal 'forbidden', but it might be.
If you create a UITabBarController from a view that's managed in a UINavigationController (ie: if you create a navigationcontroller first, and it's still around when you create the tabbarcontroller), you're starting a fight with the frameworks. Here's the admonishment from the docs on combining viewcontroller interfaces:
An application that uses a tab bar
controller can also use navigation
controllers in one or more tabs. When
combining these two types of view
controller in the same user interface,
the tab bar controller always acts as
the wrapper for the navigation
controllers. You never want to push a
tab bar controller onto the navigation
stack of a navigation controller.
Doing so creates an unusual situation
whereby the tab bar appears only while
a specific view controller is at the
top of the navigation stack. Tab bars
are designed to be persistent, and so
this transient approach can be
confusing to users.
I read that as "if it doesn't break something that we haven't thought of on the next update, we might reject the app anyway because it's 'confusing to users.'"
I suppose you could kill the whole navigation hierarchy and the navigationcontroller if you don't need to return there (like if you just used it for a one-time setup screen). Or you can look into other options for navigating within a viewcontroller that's managed by the navigationcontroller.
One thing to try might be to navigate to a UITableView, and use its cells to push a modal view onto the navigation stack. That would be familiar to users and also jive with the intent of the navigation classes.