Calling a UIApplicationDelegate method from a UIViewController - iphone

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

Related

How to reload/refresh view from app delegate?

i'm try to find a way with google to reload/refresh view from app delegate. none of solutions work. my idea was for vie to reload inside applicationDidBecomeActive: , but i can't get it to work, it doesnt matter what i try. anyone?
Update:
last thing i used (in applicationDidBecomeActive: with imported ViewController.h in AppDelegate) was:
ViewController *vc = [[ViewController alloc] init];
[vc viewDidLoad]
There were a coupled of other variations, but i think you get what i'm trying to achieve.i'm a rookie so please don't blame me if this is totaly useless :)
Do you mean that you want to perform some action (sending a refresh message to a controller, for example) when the app is reopened?
The method to override is -applicationDidBecomeActive: in your app delegate. You'll want to keep a reference to the view controller in question around. So:
#property MyViewController *myView;
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[self.myView refreshSettings];
}
You could probably use -viewDidLoad like you did in your example code, if you wanted, but I find it's easier to factor out the part that you want to update and call it from both places.

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.

iPhone DropBox App Like implementation - flipping tab bar to reveal login screen

I am writing an application where you need to show login screen modally and the app has a tab bar.
I have added tab bar directly to the UIWindow. To flip it to a new view (login view) I have overridden applicationDidFinishLaunching where I check if user has login credentials, then I do not show the login screen otherwise (assuming first time use or logout case) I modally present the login screen. I have given an option of logout in a settings tab inside the app.
I am using [[UIApplication sharedApplication] delegate] call to get instance of app delegate when user logs in first time. This way I get access to the tabBarController that is part of the Application Delegate (as is most of the times). However, when I try to call my loginViewController from the logout option in settings (somewhere in future life cycle), the same call [[UIApplication sharedApplication] delegate] returns me a delegate on which I am not able to use any of the methods I have defined. It gives me "unrecognized selector sent to instance" error at runtime.
I need to understand what exactly the call [[UIApplication sharedApplication] delegate] returns? Does the delegate object it returns change over the period of application life cycle? OR is it a singleton instance through out the app life cycle?
And secondly to resolve this, should I add the tabBar to a view (contained in main window) instead of adding it directly to the UIWindow (as done by the template for Tab Bar application and seems to be the standard practice). Are there any known problems with this approach OR its okay to do so. Any one has tried this? Please let me know.
Thanks
Dev.
It sounds like your class that gets an instance of your singleton delegate doesn't know what it implements. make sure you are #importing your delegate to the class that uses it as [[UIApplication sharedApplication] delegate]. Also, if you get a warning about UIApplication not conforming or whatever, you can cast it to your AppDelegate type to avoid it.
To answer your question about what this call returns, it is a singleton throughout the lifecycle of the app.
To answer the 2nd question, having it in the UIWindow (and thus in the appdelegate) is fine, and probably encouraged, since it is the root controller of your app (from the sound of things)

How to reference THE UIWindow from sub UIViewControllers?

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.

How can I outsource view-change-operations from my view controller upon accelerations?

I have an view controller class. I want to do some things in my view when the accelerometer detects movement and calls the accelerometer:didAccelerate: method in the delegate object.
That delegate object is the problem here in my brain. Currently, my brain is freezed and I don't get it what would be better. Let me know what you think!
Solution 1)
In my view controller class I conform to the UIAccelerometerDelegate protocol, and implement that accelerometer:didAccelerate: method.
In the -applicationDidFinishLaunching: method of my AppDelegate class I set that view controller object up as the delegate for receiving method calls upon accelerations. I think that's not really good.
Solution 2)
I create a blank new object called AccelerationDelegate, conform to that UIAccelerometerDelegate protocol, implement that accelerometer:didAccelerate: method and in the -applicationDidFinishLaunching: method of my AppDelegate class I set that view controller object up as the delegate for receiving method calls upon accelerations.
But for solution 2 my brain got stuck a little bit! How would I access the view objects from my view controller inside that object?
The problem here is, that I have more than one view controller around. I use a tab bar controller to switch between them.
Any suggestions how I could get that right?
I agree that the second method is better. Are you looking to access just the currently selected tab view, or just a specific view in your app.
In any case, what I would do is to set up properties for your UITabViewController in your UIApplicationDelegate so that you can access it from the delegate (you can get the app delegate by calling [[UIApplication sharedApplication] delegate]). For example:
YourApplicationDelegate *appDelegate = (YourApplicationDelegate *)[[UIApplication sharedApplication] delegate];
FirstUIViewController *firstViewController = appDelegate.firstViewController;
[firstViewController doStuff];
where firstViewController is a property on your delegate.
If your acceleration is specific to one view controller, then it makes sense to have the view controller receive the information necessary to alter its own subviews. However, it might be better to set your view controller to be the delegate when the view appears, and set the delegate to null when it disappears. (Specifically, - (void) viewWillAppear: and - (void) viewWillDisappear:)