Popping consecutive view controllers and returning to main view controller (using navigation controller) - swift3

I'm following the Firebase-Chat-Messenger example in the "let's build that app" Youtube videos, and it works fine.
However, I'm testing integration inside a test application :
My test app has a menu with buttons and one of them is for the chat, which takes us to a similar interface (login menu and so on, anything beyond it is similar to the example in the tutorial. But you don't need to check it to answer my question).
Main menu button => Login/Register interface => Chat interface
I can't find a way to dismiss the chat interface to return to the main menu of the app, dismiss always returns to the login/register interface and sometimes causes errors. Could you suggest a good solution to use for this?
tl;dr : How to dismiss two or more views and return to main view (main menu) of app?
P.S : I'm new to Swift and still struggling with some basic elements, Sorry if the question seems too simple.

Use either popToRootViewController(animated:) to pop to the root view controller, or popToViewController(_:animated:) and provide the spicific controller you'd like to pop to.

Related

Android navigation component- With Login screens

When dealing with login screens, I am trying to work out the better approach - either execute navigation "action" to go to login fragment on first use (and hide back button to actual app), or start a new login activity (with its own nav graph). For the first approach (just using navigation components), I do not know the way to remove the back button without a hack "hide". I tried using navoptions, setpopupto etc., but it does not work. Code below:
val navOptions = NavOptions.Builder()
.setPopUpTo(R.id.home_fragment, true)
.build()
host?.navController?.navigate(R.id.action_global_signUpFragment_dest, null, navOptions)
Two questions then:
1) How to properly handle login transition with just navigation component?
2) Is starting a new login activity, with separate nav graph, a better idea?
I think the first approach is better.
To hide the 'back' button on your toolbar inside signUpFragment you can use AppBarConfiguration, and customize which destinations are considered top-level destinations.
For example:
val appBarConfiguration = AppBarConfiguration.Builder(setOf(R.id.home_fragment, R.id.signUpFragment_dest)).build()
NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration)
This way home_fragment and signUpFragment_dest will be considered top-level destinations, and won't have back button on toolbar.
Another option for solving the back button problem is how I did it here. Also, rather than show/hide the bottom nav bar, I have two NavHostFragment, one main full screen one, and one contained within the home fragment (above the bottom nav bar).
When I want to navigate to a full screen view I call this extension function,
fun Fragment.findMainNavController(): NavController =
Navigation.findNavController(activity!!, R.id.nav_host_fragment)
then navigate via the main graph.
This makes sense conceptually to me, to have parent and child nav graphs.

Watchkit popToRootController not working

I am using a vertical page direction on my watch app, and I have a button that opens a new interface, which opens the third interface also from a button, this is done by using the modal view, and in the third interface i am calling popToRootController, because i want to go back to the first interface, but this is not working, have anyone same issue?
You need to use dismiss if you present view controllers modally using presentControllerWithName.
You can use popToRootController or popController if you present the view controllers hierarchically using pushControllerWithName.
You can read more on the Apple Interface Navigation guide.
In your example if you want to dismiss twice, you will have to pass a delegate or closure with the context to your second controller. Then you can call the delegate method or closure after dismiss() on the third controller. The implementation of the delegate method or closure will be another dismiss().

Returning to my app after navigation

As suggested in other posts I used the following code to start navigation from my GDK application. When the user finishes navigating they go back to the main "Ok Glass" screen. Is there any way to bring the user back to my app?
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("google.navigation:q="+lat+","+lon));
startActivity(intent);
This is untested, but can you try adding the following flag to your intent and see if it changes the behavior?
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

How to make an action affect a sibling view without controller.get('view')?

Quick context:
Application view has 2 outlets. One for a toolbar. The other for the routable "main" view hierarchy.
app -- main
\-- toolbar
I need some buttons in the toolbar to trigger events in the "main" view. Not update any data in any model. I simply instruct it to trigger some changes to a drawing library that the view is presenting. Clearing the canvas, resetting zoom value and such.
In 1.0 pre2 and earlier I have used actions and router.get('someController.view') to get access to the view I want and trigger the action/method/event. Hardly the pinnacle of application design but it worked fine.
This option is now gone and I am at a loss for a good alternative. What mechanism should I use when communicating between views that are not in a child/parent hierarchy? Everything I have come up with is clunky and triggers my sense that "Ember has a better way".
In short I want:
A toolbar-button to trigger an event
The main view to react to this and perform some updates on parts of itself.
The main view to NOT re-render in the Ember sense of the word as would through routing. It uses a drawing library and integrating all it's properties and behavior into Ember models and controllers would not be a lot of fun.
The toolbar and the main view share a parent view but are on different "branches".
Poor Options I am considering:
The toolbar is very much an application level concern but it does have some buttons that need to instruct specific views. One option I see within Ember is to nest the toolbar under the "main" view. This seems wrong for some of it's other functions.
Communication could be handled by a controller (and possibly even a model) that would hold properties that the toolbar sets and the "listening" view reacts to and resets the value of. This sounds like abuse of the controller and model purposes and like a pretty poor event listener setup.
I could make the drawing library an application global as App.Drawing or something but that does also seems bad. It would also mean that the actions still would not be able to make use of any data in the view to update the drawing library with.
Any suggestions?
What mechanism should I use when communicating between views that are not in a child/parent hierarchy?
In a typical ember application this communication should happen between controllers. Otherwise "Poor Option 2" is on the right track:
Communication could be handled by a controller (and possibly even a model) that would hold properties that the toolbar sets and the "listening" view reacts to and resets the value of.
Consider using two controllers. Toolbar actions will target the ToolbarController, which is responsible for maintaining the toolbar's state and for changing main in response to user action. ToolbarController should declare a dependency on MainController via the needs property. For example:
App.ToolbarController = Ember.Controller.extend({
needs: ['main'],
buttonOneGotAllPressed: function() {
main = this.get('controllers.main');
main.turnOffAnOption();
main.makeSomeOtherChange();
}
});
Now MainController can be focused on the state of MainView. It should not be aware of ToolbarController or it's buttons.
This sounds like abuse of the controller and model purposes and like a pretty poor event listener setup.
Agreed it would likely be an abuse of model purposes but it is exactly what controllers are for.
This is definitely not an event-listener setup, but that does not seem a good fit in your case. The toolbar you describe seems to exist only to interact with the main view, so it makes sense to have a toolbar controller that depends on main and interacts with it directly.
If the components are truly decoupled then an observer (Pub/Sub) pattern might be more appropriate. See How to fire an event to Ember from another framework if that's of interest.

Nesting UITabBar into UINavigation Controller

Hiya, I would like to know if there's an example of this anywhere. Basically I would like to push the UITabBar, and keeping with apple's guidelines I can only do this by placing the UITabBar(not the controller) in a viewController. Examples of this are in the Music selection on your iPhone/iTouch when you hit the "Now Playing" nav item, notice the tab bar pushes over.
This is somewhat of the flow I'm trying to accomplish
-----> Table (cell 1)----> Detail View
|
Navigation Controller ----> UITabBar-|----------> view 2
|
-----> view 3
So when the app launches I'm greeted with my tab bar and when I select a cell from the tableView the detail view is pushed onto the stack resulting in a possible customized button bar at the bottom of that view.
Another good example of this functionality is the [B]NYTimes [/B]app (it's free if you want to check it out)
Now I got the basics of this running, but I'm getting crashes when trying to wire IBOutlets to the tab items in IB. Would appreciate some insight on this.
Thx much!
It's pretty easy. The viewcontroller you push on the stack (the one which should hide the tabbar) should have the hidesBottomBarWhenPushed property set to YES.
viewcontrollerbeingpushed.hidesBottomBarWhenPushed = YES;