How to reference THE UIWindow from sub UIViewControllers? - iphone

I am trying to add another subview programmatically based on some event (user taps a button, for instance).
My problem is that I am having problems referencing the (one and only) instance of UIWindow. I reach it from my appDelegate, because the MainWindow.xib and the appDelegate have been wired up. But I cannot reach the UIWIndow from anywhere else (I cannot draw that connection in IB, can I?)
What techniwue is preferred to get a reference to (the one and only) UIWindow? ...so that I in turn can use the following code from my various UIViewControllers:
[myOneAndOnlyWindow addSubview:oneOfManyViews.view];
[myOneAndOnlyWindow makeKeyAndVisible];

You can retrieve pointer to the key window of your application after call
[UIApplication sharedApplication].keyWindow
Window becomes key after you call
[window makeKeyAndVisible]

You can use following code to add view in main window from any view controller:
YourAppDelegate *appDelegate = (YourAppDelegate*)[[UIApplication sharedApplication] delegate];
[appDelegate.window addSubView:viewController.view];
The only thing you must take care is that window should be defined as a property in your application delegate class.
Hope this helps.
Jim.

Related

iOS - Accessing viewControllers on storyboard from appDelegate

I've got an app using Core Data where I'm creating a managedObjectContext in the app delegate.
I want to pass that managedObjectContext to two view controllers on my storyboard so they are using the same managedObjectContext to save and fetch to and from.
I can access the first view controller with:
self.window.rootViewController
But the second view controller I want to access is then after a segue from the first and no reference is returned from it.
I tried:
instantiateViewControllerWithIdentifier:
But that creates a new instance of the view rather than allowing me to access the second view controller that appears after the segue.
So my question is, how can I access the second view controller?
Or (as I'm very new to this) is there a better way to be managing/passing the data between the view controllers?
Thanks in advance.
Or (as I'm very new to this) is there a better way to be managing/passing the data between the view controllers?
It depends on the data you're trying to pass around. In this case, you want to give your view controllers access to your Core Data managed object context. Because this is something you're going to need throughout the lifespan of your app it would be better to have your view controllers access it via your application delegate.
You can do this via [[UIApplication sharedApplication] delegate] - however, you may need to typecast it to avoid compiler warnings, or alternatively you might want to create a macro that returns the managed object context to save you time and make your code a little more readable.
If you told XCode you wanted to use Core Data when you created the project you should have the methods to retrieve your object context already in your app delegate. If not, you'll need to create them.
To create a macro to save you having to write out [[UIApplication sharedApplication] delegate] every time you need to access the managed object context, check out this answer: Short hand for [[UIApplication sharedApplication] delegate]?
You can go through this :-
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
MasterViewController *result;
//check to see if navbar "get" worked
if (navigationController.viewControllers) {
//look for the nav controller in tab bar views
for (UINavigationController *view in navigationController.viewControllers) {
//when found, do the same thing to find the MasterViewController under the nav controller
if ([view isKindOfClass:[UINavigationController class]])
for (UIViewController *view2 in view.viewControllers)
if ([view2 isKindOfClass:[MasterViewController class]])
result = (MasterViewController *) view2;
}
}

Using 1 AppDelegate for multiple .xib xcode/ipad sdk

Is it a good practice to use one main AppDelegate.h to handle all the ibaction stuff?
is it even possible? if so who does one do this? my IB only lets me link to the associated .m file
firstView.xib only respond to ibaction in firstView.m
I want a button on firstView.xib to respond to ibaction in AppDelegate.m
any thoughts?
No, it's not good practice. But if you really want to...
If you aren't worried about having the same instance of appDelegate holding the IBActions, you can just drag a generic object from the library into your firstView.xib, then change the class to appDelegate. That will allow you to link actions.
You can hook up the actions programmatically: create IBOutlets from the view controller, and in the viewDidLoad method of the view controller, get the [[UIApplication sharedApplication] delegate] and attach it's IBAction methods to the actions of the IBOutlets for the buttons
To access the app delegate from elsewhere in your code, do the following:
#import "AppDelegate.h"
AppDelegate * appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];

Passing a managedObjectContext through to a UITabBarController's views

I have an app which is based on the Utility template (where you flip over the view to see another). On the first view there is a login screen, then it flips over to reveal a UITabBar style interface.
I'm having trouble working out how to pass the managedObjectContext from the App Delegate (where it is created) all the way through to each of the Tab Bar's views.
App Delegate's managedObjectContext get passed to FrontLoginViewController which gets passed to BackViewTabBarViewController .. where next?
The BackViewTabBarViewController nib has a UITabBarController with a UINavigationController for each tab.
Sounds like the managedObjectContext is defined in your AppDelegate. If so, then...
From whatever viewController you want... just call
MyApplicationDelegate *appDelegate = (MyApplicationDelegate *)[[UIApplication sharedApplication] delegate];
Then use...
appDelegate.managedObjectContext
whenever you need the managedObjectContext. Change the MyApplicationDelegate to your AppDelegate and you should be good to go.
I've ran into this same problem, i'll share my solution.
First you need a reference to the Nav Controller in the Tab Bar in the nib file, make sure you connect it up.
IBOutlet UINavigationController *navigationController;
Then, get the Controller as recommended in the support docs and send it the managedObjectContext:
SavedTableViewController *saved = (SavedTableViewController *)[navigationController topViewController];
saved.managedObjectContext = self.managedObjectContext;
Alex (from another post) is right, "You should generally stay away from getting shared objects from the app delegate. It makes it behave too much like a global variable, and that has a whole mess of problems associated with it."

Switching to another View with UITabBar

I just started developing with the iPhone SDK and I have a problem with switching to another tab with the UITabBar.
This is my current code, and it works so far:
myAppAppDelegate *appDel = (myAppAppDelegate *)[[UIApplication sharedApplication] delegate]
[appDel.tabBar setSelectedViewController:[appDel.tabBar.viewControllers objectAtIndex:5]];
But if i go to the more tab and rearrange the tabbar items, the index of the viewControllers change too. Is there any possibility how I could solve this problem?
First of all, if you ever find yourself typing this:
(myAppAppDelegate *)[[UIApplication sharedApplication] delegate]
You can probably benefit from a better design. This code probably comes from a view controller, in which case you are calling out to the App delegate from a view controller, and dealing with stuff you shouldn't have knowledge of (the tab bar).
A better design is to delegate out to the app delegate, and the app delegate switches the tab for you. The app delegate should have references to the actual view controllers in the tab bar (you can hook these up via IB if not) so you can call setSelectedViewController: with the correct object, rather than indexing into the tab bar's array:
/* Somewhere in the app delegate */
- (void)selectFooBarController {
[self.tabBar setSelectedViewController:self.fooBarController];
}
Now if you don't want to bother with delegation you can just put a method on the app delegate (like the one above) and your original code becomes:
myAppAppDelegate *appDel = (myAppAppDelegate *)[[UIApplication sharedApplication] delegate]
[appDel selectFooBarController];
Again you will need to add IBOutlet properties to your app delegate which you connect to the fooBarController etc. in Interface Builder. This will let you directly reference them rather than grabbing them out of an array.
The most straight forward means I can think off relies on the fact that when you application first starts, unless you are doing something to save the re-ordering, you could save off the initial list of UIViewControllers:
initialOrdering = [[appDel.tabBar viewControllers] copy];
Where 'initialOrdering' is an NSArray* which you would then use instead of appDel.tabBar.viewControllers in the code you posted.

Calling a UIApplicationDelegate method from a UIViewController

I have a simple iPhone application that is very similar to the Page Control example provided by Apple. It creates a group of UIViewControllers dynamically, then adds them to a ScrollView.
When a button is touched on one of these views, I need to be able to call a method back in the UIApplicationDelegate. It will then do some calculations, and generate a new set of views to display.
I'm not sure how to make this happen. It would seem like this would work, but it doesn't:
[[self superview] doSomething];
What am I missing? Thanks.
[[(MyAppDelegate*)[UIApplication sharedApplication] delegate] doSomething]
Replace MyAppDelegate with the name of your App Delegate class