views:

311

answers:

2

I have two View Controllers: TableViewController (which is used as a modal view controller) and ToolbarController. In Interface Builder I have ToolbarView, which is controlled by the ToolbarController.

ToolbarView has an IBOutlet UIWebView that ToolbarController controls (uses buttons on a tool bar to switch pages in a webview).

What I need is the ability to have TableViewController to change the UIWebview in ToolbarView.

How can I accomplish this?

TableViewController.h:

#import <UIKit/UIKit.h>
#import "ToolbarController.h"
#import "MyAppDelegate.h"


@interface TableViewController : UITableViewController {
    NSMutableArray *widgetList;
    IBOutlet UIWebView *webView;
}

@property(nonatomic,retain) IBOutlet UIWebView *webView;

@end

TableViewController.m:

    #import "TableViewController.h"
    #import "MyAppDelegate.h"
    #import "ToolbarController.h"
    #import "TableView.h"

    @implementation TableViewController

    @synthesize webView;

    //Lots of working code omitted
//didSelectRowAtIndex below should change the webView in ToolbarView to Google's homepage but does not.

        - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
            NSString *urlAddress=[NSString stringWithFormat:@"http://www.google.com"];
            NSURL *url = [NSURL URLWithString:urlAddress];
            NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
            [webView loadRequest:requestObj];
            [self dismissModalViewControllerAnimated:YES];
        }

        - (void)viewDidUnload {
            // Release any retained subviews of the main view.
            // e.g. self.myOutlet = nil;
        }


        - (void)dealloc {
            [super dealloc];
        }


        @end
+2  A: 

I would suggest using delegation to handle this task. Set up a delegate protocol such as URLSelectionDelegate that will be implemented by your toolbar view controller. You'd probably just need one method, such as -urlSelectionDelegateDidSelectItemWithURL:(NSString *)selectedItemURL or similar. That way your modal table view controller is only responsible for its parent when an item was selected, and you keep all of your UIWebView-related logic in the same place, in the toolbar view controller.

You would declare the delegate protocol in its own file, or simply in your toolbar view controller's header, as such:

@protocol URLSelectionDelegate <NSObject>
- (void)urlSelectionDelegateDidSelectItemWithURL:(NSString *)selectedItemURL;
@end

Your web view controller would then implement this URLSelectionDelegate protocol, meaning that it implements the urlSelectionDelegateDidSelectItemWithURL: method:

@interface TableViewController : UITableViewController <URLSelectionDelegate>
// ...
@end

Now you'll add a property to your modal table view controller named "delegate" or "urlSelectionDelegate":

@property (nonatomic, assign) id<URLSelectionDelegate> delegate;

and set that to the parent view controller when it's initialized:

// Initialize table view controller (keep your existing code)
TableViewController *vc = [[TableViewController alloc] init];
// Assign the delegate
[vc setDelegate:self];

Now, in your didSelectRowWithIndexPath method, you'll call the delegate method accordingly:

if ([self delegate] != nil && [[self delegate] respondsToSelector:@selector(urlSelectionDelegateDidSelectItemWithURL:)) {
  [delegate urlSelectionDelegateDidSelectItemWithURL:@"http://www.google.com/";
}

Then just put the logic to change the web view inside the parent view controller.

You can read a lot more about your different options in "What’s the best way to communicate between view controllers?" and you can learn more about the delegation pattern in Objective-C in How do I create delegates in Objective-C?

pix0r
Would that delegate be a subclass of TableViewController?
LoganFrederick
A delegate is actually a protocol, which is very similar to an interface in other OO languages. It is something that a given class implements, but subclasses are not involved. I just added a lot of code that will helpfully demonstrate how you could use delegates in this scenario. You'll learn a lot more if you click through to those links I provided. :)
pix0r
pix0r, you are my hero. Thanks!
LoganFrederick
A: 

Is webView initialized to the one in ToolbarView? Typically I would do that by adding my own init method on TableViewController which passes a reference to that object.

chrisbtoo