I just started development in WatchKit. Suppose I have views appearing in sequence A-B-C-D-E. From view D, I want to land on view B or C (intermediate view). How it this achieved in a WatchKit app?
After waiting for a long time, Still no answer. So, I am posting a work-around that I did in my app.
I made a use of flag. When you reach the D viewController set the flag to 'true' and implement the logic to pop C viewController (based on flag value) in C's willActivate method. Similar thing can be done in any number of previous view controllers that you want to pop (i.e B, A, etc.). Also, don't forget to reset the flag or your VC will automatically get popped everytime you go to that VC.
Related
I have two view controllers A and B and a segue from A to B (type: show) through a next button and a segue from B to A (type: show) through back button. I am passing some data through segue A to B. Data is displayed correctly if I just tap next from controller A and go to controller B.
However, If I tap next and go to controller B and hit back and come back to A and then hit next again, it doesn't work. Any ideas whats going on here? Sorry for the confusing language.
Sounds like your "B to A" is wrong, you're using a navigation stack so you should only push (show) when you are moving forwards. When going backwards you should pop off the top (dismiss)
If you keep pushing, the app will continue to just put more and more ViewControllers in memory, which is bad.
I suspect whats happening here is View A initially has the data and passes it to View B. Then when you press your back button it creates a new copy of View A which doesn't have the data and shows that instead of the original View A.
In Short: (A to B :type - show) (B to A :dismiss the current ViewController)
I agree with user2877496 in that you should not use a regular segue to go back from B to A as you will be adding "A" onto the stack each time.
I just wished to add that one method to dismiss B and go back to A is by using an Unwind Segue.
The Apple documentation covers this quite well
https://developer.apple.com/library/content/technotes/tn2298/_index.html
Did you resolve this? My guess is you put stuff to execute in viewDidLoad (which only runs once at the start of your app) and it needs to be in viewWillAppear so it is called each time you return to your main view controller. Please provide your code for those methods if you require further help.
I'm using storyboard with a UINavigationController that has view controllers A, B and C.
A is the root view controller of the navigation controller which at startup fetches some data. If I click on a row in A that will segue to B view controller with that data. Clicking on a row in B will segue to C view controller.
Later in my app for instance I'm inside C and the user wants to refresh the data. Meaning I need to fetch the root data for A view controller again.
How do I rebuild my navigation hierarchy again after the user have refreshed the data? I need to update the data source in A and then in B and then finally in C somehow.
It's merely a matter of planning ahead, isn't it? It's your program so it's your job to provide yourself with the facilities that you will need. In this situation there is no need to "rebuild" anything (though you could do that, I suppose). A and B both do still exist even while you're showing C, so all you have to do is communicate with them as needed. If the data-fetching power resides only in A, then simply provide A with a method that C can call in order to request the refresh and receive the updated data. If A and B are subsequently shown again (because the user pops back from C), they will of course use their viewWillAppear to update their respective interfaces as well. But at the moment A and B are merely objects, and communicating between objects is, after all, what object-oriented programming is all about.
You should put all the logic of A in another objet which could be accessible from A and C.
I think this post is a good place to start
This is a common problem and for everybody who still doesn't know the correct way how to deal with that, here is the scenario.
Modally presented view controllers A -> B -> C
Now you want to dismiss C with B at one smooth animation landing to view controller A. So apple documentation says that you only need to perform:
[A dismissViewConttollerAnimated:YES completion:nil];
And C with B should be nicely gone. This is really often needed scenario and I'm really said and disappointed that the common use case is not working properly. Why the top view controller C disappears in a moment and B view controller appears with dismissing animation instead of C to be visible for the whole animation process? I would really except to see only C view controller's dismission.
The best solution to use in this case is Unwind Segue. You can directly move switch to any view controller in the heirarchy.
The dismissal of B can't be done in parallel with dismissal of C. This happens sometimes in iOS when the two animations are related somehow - I don't know the exact details.
If you put a breakpoint in C's dismissal completion block, you'll probably see the finished parameter being false, indicating C's animation has been interrupted.
I think the correct solution is to dismiss B only. C will be gone automatically since it was presented by B.
I have three view controllers A, B and C.
C is the target.
From A, I have a segue named showCFromA to view controller C.
From B, I have another segue named showCFromB to view controller C.
Now, when C is displayed (shown from B), I tap on the "Back" button, but at this stage, it shows A, and not B as I expected.
How can I fix that?
Don't mess with Back - it makes for a disjointed app experience. You end up at a place you don't expect to be and navigation just doesn't feel right.
If you have a B on the stack, you can just
popToViewController:animated:
to return to the specific view controller (B) that you want to see.
If you have gone from A directly to C with no intervening stop at B, you can't go there with back. Instead you should just push a B.
If your B should be on the stack - i.e. you went from B to C - then B is where you should end up if you simply go back. If that is currently not the case you need to post some more details to help diagnose the problem.
What is confusing right now is what you actually have on the stack. You mention being at A and going to C, then being at B and going to C, but the order in which you do this (and if these are two separate cases) affects the outcome.
After checking the source again, I found the issue is not properly handling navigation vc stack. When push new VC from B, when viewWillDisapper is called (B), I added "popViewController". Therefore, navigation view controller array has count of 2 (the middle element is removed). This makes strange behavior: From view controller C, I cannot go back.
I have 2 views, A and B. A is a tableview, and B is a detail view. When a cell is tapped in view A, the appropriate data is loaded in view B and I use [self.navigationcontroller pushviewcontroller] to present it. This all works fine, but if the user presses row 10, lets view B load, goes back, and presses row 10 again, I would like for it to just go forward to the view B that is already loaded. The navigationcontroller always lists as only having one view in the stack. Do I have to manually save a view to the navigationcontroller to re-present? The project uses ARC and Storyboard if that makes a differance. Thanks
For this actually you dont even have to concern yourself with navigationcontroller. Have a UIViewController variable (lets say lastViewController) in your ViewController1 where viewA and viewB reside.
Before pushing ViewController2 the detailed view store that reference in lastViewController. When you pop back and press another row, check if its that same viewController and show the same viewController.
But I would advise against this approach. Keep it simple, let ViewControllerB load again. There could be a scenario where loading again is preferential as it might show the user more latest information row10.
The behavior you are seeing is correct! When ViewController B is needed it is created and pushed onto the stack of the navigation controller and we see view B. When the user goes back to ViewController A and we see view A, ViewController B is no longer needed, and it and its view go out of existence.
This is efficient and lightweight and makes perfect sense. Once you are back in ViewController A and view A, who knows what row the user will tap now? If the user taps row 10 and goes back to A, taps row 10 and goes back to A, over and over, a new ViewController B will be created and go out of existence each time. So what? From the user's point of view it is perfectly consistent; it looks like the same view B! That is all that matters. You don't want to go back to the same view B; you want to create view B all over again. And that is what you do.
Indeed, this is the genius of iOS. With a single tiny screen, it is able to make views come and go without burdening memory and other resources.
For more about UINavigationController architecture, which is what you're using here (master-detail), see my book: http://www.apeth.com/iOSBook/ch19.html#_navigation_controllers