views:

61

answers:

2

I'm a newbie doing Objective-C, coming from Flex/Actionscript development.

I have an iPhone app with an UIApplicationDelegate conforming delegate called MyAppDelegate - it has a UIWindow.

Instead of adding buttons, labels and whatnot directly to the window, I guess I'm supposed to make a child class of UIViewController for every screen I wanna make. When that screen should be displayed, I add the respective controller's view to the window as a subview. When another screen should be displayed, I should pop off any other view from the window and add the new view. Hope I got everything correct so far...

My intent is to make each view controller only know about its own things, so let's say I wanna call view A from view B, in ActionScript I'd add a button in A firing off an event which would be caught in view A's owning object (could be the application), which could take proper action (remove view A, instantiate view B and display it).

How do I do this in Objective-C?

+1  A: 

If you're coming from Actionscript you may be interested in looking at the PureMVC framwork for objective C. Using PureMVC you'll create a combination of Mediators, Commands, and Models for application interaction.

With PureMVC you register notification with the facade, and you define listeners in your mediators to respond to these. This is pretty close to the event model you're used to in Actionscript. (At my last job we added some categories to the UIResponder to remove some of the cruft in doing this). If you're creating a considerably sized application, then I would recommend you give it a look; it certainly helped us keep everything manageable.

If you don't want to pull in a third party library then you should define your view manipulation code in your MyAppDelegate and use the [UIApplication sharedApplication] class method to access the globally shared instance.

sdolan
+1  A: 

A UIControl, such as UIButton, can have any number of event listeners registered with:

- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents;

The target would be the view controller you want to receive the method, and the action is the method you want called. For a button, events is usually just UIControlEventTouchUpInside. If the target is nil, the event will pass up the responder chain until a responder implements the action. If you pass @selector(buttonClicked:) then the target should have this method:

-(IBAction) buttonClicked:(id)sender;

The sender will be the button that was clicked. IBAction is equivalent to a void return type. You can bind the action in Interface Builder if you prefer that to doing it programmatically.

When another screen should be displayed, I should pop off any other view from the window and add the new view.

This is basically correct, but usually you use a meta view controller like UINavigationController to manage view controllers. Even if you do not use the UI that a meta controller might present, it is convenient to have view switching managed for you.

drawnonward
Like you note, I've now seen that using UINavigationController (or the tab controller) would be preferred. These controllers however always (more or less) stay visible on screen, ie you have a bar on top or bottom containing main nav buttons. My app however is a doc viewer, where viewing the document is central (could consume lots of memory), still after long contemplating I didn't find a ready-made controller for this. The doc view would be the first on launch, and should take 100% of the screen, without nav bars. On another view, I want to unload the document view completely to save memory.
Jonny
With a navigation controller, use `navigationBarHidden=YES` to hide the navigation bar. Set it from `viewWillAppear:` of each controller that is pushed.
drawnonward
Meta view controllers add and remove the views of view controllers they show. After `viewDidDisappear:` is called, you are free to release any views and other resources as long as you can create them again in `loadView` or `viewWillAppear:`.
drawnonward