SwiftUI Navigation Stacks for different levels with in the app - swiftui

I have this TabView based SwiftUI app and each tab has its own navigation stack which works as expected and there are no issues because all my 4 tabs have 4 separate independent navigation stacks.
However, in many cases, on those navigations, I want to provide the navigation on top of tab bar so that it looks like a real push happening on top of main tab bar. If I add NavigationStack on top of tab view then app crashes. For now I am using .toolbar(.hidden, for: .tabBar) API but that looks like a hack because it does not have same effect as it would be if there is push on top of tab bar.
So how can I have one global app level navigation stack that is parent of whole app and also local navigation stacks one for each tab item. And if I use global navigation stack it should push on top of tab bar and if I use local navigation stack then it should push within that tab only. 
I have seen Facebook messenger apps "People" tab and "Settings" tab are showing this working but I dont know how did they do that.

Related

Set active tab when navigating from one tab to another by button click

I have been struggling with this for a while now. I'm trying to navigate to one tab (let's say Home) to another (let's say About). I'm able to navigate that either the page get's added to nav stack, but then it's not changing active tab. That, or then we use select to set the active tab, which means that I lose the navigation stack. Here's the latter option code:
export class HomePage implements OnInit {
tab: Tabs;
constructor(public navCtrl: NavController) {
this.tab = this.navCtrl.parent;
}
navigate() {
this.tab.select(1);
}
But this means that as mentioned, I lose the nav stack and can't use the back button that would show if I use push. That brings us to the other option, when I use .push():
this.navCtrl.push(About)
The active tab won't change, but still shows Home as the active tab, even though we are successfully navigated to About tab.
So what I wish for, is to have both the 'Back' button and the active tab (About) selected when I'm clicking the button to go to About from Home. Here's a demo with the push option, as you can see the active tab does not change: https://plnkr.co/edit/6KIL8mxfTMCsvACpiD1K?p=preview
PS. I looked at this question, but it wasn't useful to me: Changing tabs dynamically in Ionic 2
I'm using Ionic 3
I don't think this is how the tabs component is intended to work. With tabbed navigation you kind of have n navigation stacks (where n is the number of different tabs you have) which means if you .push() a new page on the nav-stack you push it on the stack of the currently selected tab.
Switching to another tab kind of is the same as starting with a new root, you start with the initial page ([root]="yourFirstPage") and can then add new pages to this particular nav-stack (and you can pop them off the nav-stack with a back button).
In you particular example you are trying to .push() the About page on the stack of the Home page and expect the NavController to know that you intended to switch to another stack and to push a new page to the new stack.
One solution to your problem could be to always remember the previous tab when you use .select() and display back button manually in the navbar which uses .select(previousTab) on click.
I hope that makes things clearer for you.
It's the default behaviour to act like this. When you select a tab it clears the nav stack and set the root to another page. When you push your about page when in home page you're pushing a new page in your home nav stack, this is why it doesn't change and shoudn't change.
The reason to use tabs is that you can segment and divide stuff in they correct categories. When updating a product you don't whant the user the see, for example, billing information in the same stack of products since it doesn't belongs to that category.
The .select() method (whose you've implemented in your home.page.ts) is the closest you can have from beeing able to select a tab without clicking in a specific tab.
What you can do is simply remove about from beeing a tab and push it in home OR remove the button to go from the home to about page, since there's already a tab for this.
In any case what you want to do is an error that Ionic team removed the possibilities from people doing.
Hope this helps you.

How to navigate to another view controller in the same tab of the tab bar controller in swift 3?

I have a tabbar in my app and in one of the tabs I want to navigate to another view controller - I know how to navigate But the problem is when I used that I can't see the tab bar in the bottom that means I can't go to the other tabs when I navigate
Hard to answer without a visual but it sounds like your hierarchy is off. Make sure any content like background images aren't above the nav bar in your view or else it will block the nav bar when you run the app.

How to expose standard back button in view controller navigation?

I need users to be able to navigate a data hierarchy (master level, detail level) and to create new master and detail objects accordingly. Both master and detail use arrays for their model and TableViews for presentation
The navigation flow for this uses 2 navigation and table controllers like below. The + of the master and detail TableViews create new objects, the forstTableCell navigates to the second TableView using a segue:
While the screenshot shows "Done" right now even when removing that ButtonItem the slot remains empty.
I would like to show the standard back button instead: "< Middlewares" in this case. In the tests I've only been able to get the back button when navigating to a normal ViewController, but not to another NavigationController. Is it possible to have it between Navigation Controllers, too?
Simply remove the second navigation controller. If you use a push segue, your second view controller will still have the navigation bar. As long as you don't use a modal segue all view controllers that are pushed will have a navigation bar.
So your storyboard will look like this:
You will then automatically have a back button. If you want to change the text of it, go to your navigation item of your first view controller and change the back title accordingly as shown in this screenshot
You certainly want to have a title in your second view controller (something like "Add [whatever you want to add]". So simply drag & drop a UINavigationItem on your second view controller then you can also add UIBarButton items in your Interface builder
Controlling the look/feel of the Navigation Bar Buttons
You can achieve the behavior you want by opening the Document Outline and find the existing Done button. If you have a UIBarButtonItem type, you can simply change the type to Custom in the Inspector. Next add a regular button within the UIBarButtonItem (just bring the Navigation bar for the target controller into the zoomed in view of the storyboard/xib). This will allow you to drag a button onto the navigation bar.
Once you have a standard button you can add an image with the back arrow. Then add supporting code to use the pop behavior on the Navigation bar. Since you can have only one root navigation controller, you may want to remove the second UINavigationController and add a UINavigationItem from the objects library and then subsequently add the buttons, titles of your choice. This configuration will allow you to leverage all of the push and pop methods available, while retaining full control of the look/feel/behavior of the navigation stack.
More on customizing the look/feel/behavior of the UINavigation Stack can be found at: Navigation API Docs

TabBar inside detail view of SplitViewController.

I am trying to embed a Tabbar in the Detail side of a Split View Controller. The way I have done is that in the Storyboard I have the TabBarController as the DetailViewController and from there I have a couple of Navigation Controllers hooked to views ( separate tabs which are of type DetailViewController).
The problem I am facing is that out of two tabs which I have added, only one tab shows the button for showing the Master view in the Portrait mode.
I am new to iOS development, and would deeply appreciate any help towards solving this.
Thank you for your time.
From the documentation for the UITabBarController: "When deploying a tab bar interface, you must install this view as the root of your window. Unlike other view controllers, a tab bar interface should never be installed as a child of another view controller."
http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UITabBarController_Class/Reference/Reference.html

How to show a ‘modal’ view (controller) *in* a tab bar interface without hiding the tab bar

I want to implement a ‘modal’ view like the ‘search’ view of the AppStore on the iPad.
When shown, it should:
Still show the tab bar. Selecting any of the items should take you to their view as normal.
No tab bar item is highlighted (because the search view is ‘modal’).
The closest I’ve come, with existing APIs, is:
On the ‘search’ view controller, set the UIModalPresentationCurrentContext modal presentation style.
Show ‘search’ view controller modal from the active view controller inside the tab bar controller (not from the tab bar controller itself).
However, this does not seem to be the right path:
View controller is shown underneath the status bar. I can work around that from -[UIViewController viewDidAppear:], but when changing the orientation of the device, this leads to all sorts of drawing issues and the controller, again, tucks itself underneath the status bar.
Tab bar item is still highlighted.
to keep showing the search bar just trim the modal view's hight so that it doesn't cover the tab bar.
For orientation changes, you just need to handle that by changing the view size and making sure the modal view is always brought to the front of all the views. You can modify that view's frame and contents programmatically or you can just create nibs for the orientations you want to support and load them up when it changes. Also note if you do change the view's frame programmatically you will probably need to resize/reposition fields as well.
For dealing with the tab bar, you should be able to turn off the highlighted item. So when you pop up the modal also make sure to turn off the highlighted item. If you want to interact with the toolbar from the modal view you can do that with delegates, passing an instance of the parent view (or just accessing parent view... I think you get that for free)