How to Dynamically Swap-Out View Controllers Within TabBarViewController? - iphone

So this is pretty advanced and I am not sure if it is feasible in the iOS SDK but here goes (please read carefully, I don't want skimmers preemptively answering this question before they know the details):
I have a tab bar view controller with two tabs. One tab (view controller 1) holds a data-presenting view controller, and the other (view controller 2) is a settings view. In the settings view I allow the user to specify whether they want to view a simplified or advanced version of the interface of view controller 1.
What I need to do, is based on these settings, present the chosen view for view controller 1, and I want to be able to do it on the fly (the user doesn't have to close and then reopen the app). I attempted to recreate the view controller array of the tab bar within
- (BOOL)tabBarController:(UITabBarController *)tabBarController
shouldSelectViewController:(UIViewController *)viewController
but it just caused my app to crash (SIGABRT crash), go figure...
I was thinking of making a "hollow" view controller that would be able to point to the appropriate class type but the challange I have there is making it completely transparent to any view I should choose to place in it (UITableViewController, UIViewController, etc.).
Any ideas? Thanks in advance!

Have you tried looking at the docs at all UITabBarController?
- (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated

Related

iOS7 UITabBarController not responding after programmatically changing selectedViewController or selectedIndex

As stated above I'm having problems regarding UITabBarController or specifically the tab bar not responding after manually/programmatically setting the selectedViewController or selectedIndex. This also happens when I pop the view controller of the previously selected tab before moving to another tab screen. Yes I believe I have checked the multiple times the delegate for UITabBarController and yes I have confirmed that the
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
is not being fired. Is there anyone who has experienced this?
Make sure set the delegate right, if not, the delegate method won't be fired.
Seems like loading behavior of assets might have changed in iOS7
Make sure that the view is completely loaded.
Prior to iOS7, you would create the tabbed view, push it, then select the tab.
in ios7, the view is not loaded synchronously. So while you did create it and display it, the select index gets called before it is actually shown and therefore has no effect.
At least this is what bit me as we have started to transition to iOS7

Making a UITabView show the second level of a navigation controller by default

(Apologies for not being able to embed my images yet).
Using iOS storyboards, I have a UITabBarController with a UINavigation Controller/UITableView(1) embedded in it. This UITableView(1) then calls another UITableView(2):
What I'm trying to do is to make UITableView(2) appear when the Tab Bar is changed to that tab, and then have the UINavigationBar left arrow button exist to get back to UITableView(1).
The existing functionality I can think of which does this is the iPhone Mail app, where when you launch it you see your Inbox, and you can hit the left-arrow Mailboxes button to get back to your mail box list.
I've tried attaching the tab bar directly to UITableView(2) but it doesn't work as expected, there's no left arrow back button to get back to the previous view when the app is run.
I've also tried adding a navigation controller to that UITableView(2) and the Navigation controller correctly appears, but still without any back button:
Any suggestions as to what I'm doing wrong would be greatly appreciated, I'm fairly new with storyboards and it's difficult to find what to search to get this working.
If it's not possible with just storyboards themselves, is there some kind of automatic (non-visible) push to the 2nd UITableView I could do?
Thanks!
Nick.
This tutorial will definitely help you : http://maybelost.com/2011/10/tutorial-storyboard-in-xcode-4-2-with-navigation-controller-and-tabbar-controller-part1/
I ended up implementing it the following way, as I wanted to perform the majority of the work within storyboards.
I set up the storyboard with the tab bar embedding the UINavigationController, which contained UITableView(1) which then contained a custom segue to UITableView(2):
Then within the class associated with UITableView(1) I added this single line:
- (void)viewDidLoad {
[self performSegueWithIdentifier:#"campaigns" sender:self];
...
}
On load of the tab, the viewDidLoad of UITableView(1) instantly calls UITableView(2) without any kind of animation, showing the back button to UITableView(1), which is exactly what I wanted.
Thanks to those who responded!
You can implement the delegate method as below.
(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
In this method you can check for the tabBarController.selectedIndex or viewController object. This ensures the selection of correct tab , then push the controller having table 1, then push the controller having table 2.

How do I remove a view controller from my view hierarchy?

My app has a welcome screen that can only be shown in portrait mode. After the user has tapped through the welcome screen I'd like to show another screen that can be used in both portrait mode and landscape.
I have set up a view controller that implements shouldAutorotateToInterfaceOrientation: returning YES only for UIInterfaceOrientationPortrait, and I add the view to the window with [window addSubView:view]. I tag this view with the tag 1.
When the user taps through the welcome view and the app moves on to the new view I do:
[[window viewWithTag:1] removeFromSuperView];
[window addSubView:myViewController.view];
Where myViewController is an instance of the 2nd view's view controller (that handles the shouldAutorotateToInterfceOrientation method properly).
Now when I rotate, it still calls shouldAutorotateToInterfceOrientation on the original view's view controller, and does not call it on the new view's view controller.
This note from Apple says that only one view controller will get rotation notifications; however, I have removed the other view controller.
What am I doing wrong?
actually that note doesn't say that "only one view controller will get the notifications" but instead it says that "Only the first view controller added to UIWindow will rotate.".
So this might be the problem.
To resolve it, i would say to always have a view added to your window (call it permanent), and add your welcome screen and the next views to this permanent view.
Hope this helps.
as the note you link to state:
Only the first view controller added
to UIWindow will rotate.
So put a flag that makes sure that shouldAutorotateToInterfceOrientation returns NO until the user have dismissed the screen - and then returns YES afterwards. This is a simple and working solution - however, from a code readability point it might be confusing that a "dismissed" view actually controll the rotation.
Personally; my experience is that it's not really worthwhile having some views rotating and some don't - and users tend to don't like it.
happy coding
I wrote up a quick test that shows what you are trying to do should work. Here are the basics I did:
Create two view controllers. App starts with the first view controller being set in the AppDelegate into an instance variable viewController through NIB files. It is then added to the window as you have written.
I then setup an action that when called (could be a Timer, button on first view controller, etc.) that performed the following:
Remove view using [self.viewController removeFromSuperview]. This is different than the way you have done with the tag.
Created second view controller and assigned it to self.viewController.
Added to window like you have specified.
Not sure what is incorrect with your code. I would guess that perhaps the first view wasn't really being removed.

How to recreate a UIViewController stack when the root view controller is a UITabBarController?

I have an app that if it is quit in a certain view, I want to restore this view exactly where the user left.
My applicationDidFinishLaunching is very simple at the moment:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after app launch
[window addSubview:tabBarController.view];
[window makeKeyAndVisible];
}
What can I do to restore a sequence of 3 view controllers that must be stacked in the tab bar controller?
Normally, the user do these interactions with the app to go in the view that I want to restore:
App pops out;
The first tab is a table view (so its the first view controller that I have to restore) and user selects a row;
The view that appears is another table view (so its the second view controller that I have to restore) and user taps a + in the top bar of this view;
The last view controller appears in a modal way (so its the third view controller that I have to restore).
I tried what the answer of this post suggests, but my tab bar controller turns out in a mess (the post don't use a tab bar controller and I'm a beginner in iPhone development, so my tries wasn't very successful).
Thanks in advance.
It doesn't sound like you're describing typical UITabBarController use patterns, where you have a series of tabs that are always available and offer different modes of use for the application. Usually recreating the state of a tab bar controller is just a matter of instantiating the tabs as usual and selecting the current tab.
A sequence of screens that provide increasing levels of detail is the normal use pattern for UINavigationController.
You may want to investigate whether you have a sane design before worrying about how to restore it.
That said, you can either recreate your whole structure in applicationDidFinishLaunching, or you can give each class the logic to recreate the view controllers and views that are downstream. I would take the latter approach.

Adding new views to a window / changing view

I asked a question on here last week and I have tried to follow examples but not having much joy,
So I am trying to create a app that will have a main window. In this window I want to be able to display 3 or 4 different views (not at the same time) which the user can select the view via a button press. I did not want to use a navigation bar if possible.
am I right in thinking that I will need
View1 .h &.m
View1controller .h &.m
and the same for the second etc
Now if the button to select view 2 is on view 1,
how do I change the view and where do I put this code?
Do I need a root-controller or am i getting confused with other ways of doing the same thing.
Thank you in advance for your help.
If you want to change between the views like in the iPod application, you can accomplish this with a UITabBarController. You would create all the view controllers, and add then to a root tabbarcontroller. The tabbarcontroller then serves to automatically switch between views for you when the button is selected.
If you have a view with a button on, and want to change the active view u can use this method from UIViewController of the active view:
- (void)presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated;