views:

3542

answers:

5

I'm making a simple tab bar iPhone application. It has two tabs, one with a UIWebView and the other with a few text fields to hold settings, and a button to save the settings.

What I want to do is reload the UIWebView when the user clicks save on the settings tab/view. I already have it saving the settings, I just need to figure out how to put in a call to make the UIWebView refresh itself.

I'm confused about how a view can send messages to another view.

+2  A: 

What I've done is have them talk to each other via the AppDelegate.

For example:

View1 will have a function that does:

MyAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    [appDelegate myFunction];

MyAppDelegate has a function called myFunction that will either do something, or call:

[viewController myViewFunction];

I've set up a pretty nice system to load multiple views (and navigate back and forth, as if they were different screens). I just haven't made time to write this up and post it to pushplay.net -- but I'll try to do so in the next couple of days...

===

EDIT: Okay, I've posted what I have. Any comments would be appreciated.

http://pushplay.net/blog_detail.php?id=27

I understand what the commenters below are saying, but I have yet to see an example that works seamlessly, based on having multiple viewcontrollers needing to navigate between each other.

Jeffrey Berthiaume
Thanks, that makes sense. Be sure to post here when you have your post showing it in detail.
Greg
You should not need to use the application delegate to proxy messages into other views. That's what view controllers are for.
Nathan de Vries
This is the right _kind_ of code but you should do it in the viewController like Nathan says. Try not to add more than neccessary to the appDelegate. It will become big enough just with the stuff it needs to own.
Roger Nolan
+3  A: 

The fact that you're using these two views inside the framework of a UITabBarController is irrelevant to the core of the problem; namely, that you'd like one part of your application to be told that something has occurred in another part. The typical way of doing this is with KVO, or by using the NSNotificationCenter like so:

// Register interest in finding out when the settings are changed
[[NSNotificationCenter defaultCenter] addObserver:myWebViewController 
    selector:@selector(refreshWebView:) name:@"settingsSaved" object:nil];

// Notify interested parties that the settings have changed
[[NSNotificationCenter defaultCenter] postNotificationName:@"settingsSaved" object:nil];
Nathan de Vries
Right except I think KVO and Notifications sounds like overkill for this problem
Roger Nolan
+1  A: 

It depends on the complexity of the specific application and the object model in that application:

  • If the views are related and the messages relevant only to the views then they can send each other messages directly. For example a view can (and should) send messages directly to it's sub views and they can send messages direcly to their parent.

  • If they views are not related but show data about the same information you should proxy messages though the viewController - this is exacly why you have a view controller.

  • If you have a complicated application with a strong MVC architecture, the communication should be done indirectly by updating the model objects and cascading this out to the views through their viewControllers.

Roger Nolan
+1  A: 

In this case you're probably better off having your app delegate assign the controller holding the web view as a delegate of your other view controller on application launch - look into using a protocol to make it clean, but for something simple you can always just declare the delegate type as your web view holding view controller.

Notifications are also a fine idea, and there is no task too small for them - but you should be aware that it's important to unsubscribe from notifications in places like dealloc. For the top level of a tab bar view controller that does not really matter though.

Kendall Helmstetter Gelner
A: 

You can always set up an instance variable in your tab view controller that points to the web view. Just set it up as an IBOutlet, hook it up in Interface Builder and then call your method on the instance variable.

.h file:

IBOutlet UIWebView *webView;

@property (nonatomic, retain) UIWebView *webView;

.m file:

@synthesize webView;

//Then later in your method
[webView refresh]; //or however you do it

Regards,

Kyle

Kyle