1
votes

I'm new to iOS dev.My project requires me to create app with a left slide drawer,which is supposed to control the main view with a web view inside.

To make them communicated,I create a delegate of KKYViewController .

@protocol KKYViewControllerDelegate <UIWebViewDelegate>
@end

@interface KKYViewController : UIViewController <UIWebViewDelegate,UIApplicationDelegate> {
    id<KKYViewControllerDelegate> _delegate;
}

@property (nonatomic, strong) id delegate;
@property (nonatomic, retain)UIWebView* webView;

- (void)handleRefresh:(UIWebView *)webView;
@end

this is my main view controller KKYViewController.m

@implementation KKYViewController
@synthesize webView = _webView;
- (void)viewWillAppear:(BOOL)animated {
    self.webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
    self.webView.delegate = self;
    [self.view addSubview:_webView];
    [self loadExamplePage:_webView url:@"http://www.google.com"];
}

- (void)loadExamplePage:(UIWebView*)webView url:(NSString*)strURL {
    NSURL *url = [NSURL URLWithString:strURL];
    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
    [webView loadRequest:urlRequest];
    NSLog(@"LoadExamplePage!");
}

- (void)handleRefresh:(UIWebView *)webView {
    NSString* strURL = @"http://www.github.com";
    NSURL *url = [NSURL URLWithString:strURL];
    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
    [self.webView loadRequest:urlRequest];

    NSString *theTitle=[self.webView stringByEvaluatingJavaScriptFromString:@"document.title"];
    NSLog(@"title:%@",theTitle);
    NSLog(@"ReloadPage!");
}

So far it works well,web view looks great.Then I wanna use the delegate from another controller KKYLeftSideDrawerControoler.This is a table and I wanna touch one of the row to make the webview jump~~~

#import "KKYViewController.h"

@interface KKYLeftSideDrawerViewController : UIViewController <UITableViewDelegate,UITableViewDataSource,KKYViewControllerDelegate>
@end

then the KKYLeftSideDrawerController.m

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    KKYViewController* webViewDelegate = [[KKYViewController alloc] init];
    webViewDelegate.delegate = self;
    switch (indexPath.row) {
        case 0:{
            UIAlertView* myAlert = [[UIAlertView alloc] initWithTitle:@"Login Successed!" message:@"~~~~" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK",nil];
            [myAlert show];
            break;
        }

        case 1:{ //Here I wanna use this to reload my webview to new url!
            [webViewDelegate handleRefresh:webViewDelegate.webView];
            NSLog(@"tend to reload");
            break;
        }

        case 2:
            break;

        case 3:
            break;
    }
}

Well,the delegate works because when i touch down the case 1 row,my console will Log the info where I put them in the *- (void)handleRefresh:(UIWebView )webView.

There comes the problem:in - (void)handleRefresh,I found that the webview didn't jump and as you can see I tryna log the title of it but resulted null~

I track the log and found the webView I refered in - (void)handleRefresh is nil.I used to think it would be the same webView as above I loaded in *- (void)viewWillAppear:(BOOL)animated *.

This drives me insane for a long while,just want your help and I'll appreciate it.

1
If you are just 1 week into iOS, don't delve too deep into things like this. You don't even have basic memory management figured out yet.duci9y
You're right so I'm heading to learn more about it.But I want a solution and also I can learn some from it.One day I go back to this may give me more helps about this.Thanks!Leoc O'Cear

1 Answers

0
votes

First of all, you need to learn that [webView loadRequest:urlRequest] is an asynchronous call, which means that the method returns before(!!) the actual work is finished.

So just after calling "loadRequest:", the page is neither loaded nor can you expect to already get the title of the page (so your „handleRefresh:" method must fail to work).

At least you need to implement the UIWebView delegate method "webViewDidFinishLoad:", which is called by the webView object when the webView did finish loading the page. If "webViewDidFinishLoad:“ is called, then you can access the title of the document and be sure that it is valid.

Also in your method "tableView:didSelectRowAtIndexPath:“ you create a new KKYViewController object each time the user selects on a table cell. But you never add this view controller into the controller hierarchy of your App. So it’s never inserted into the view hierarchy of your App and so the „viewDidAppear“ method is never called. And so the webView is never created (and therefore nil).

Another remark:

I’d avoid to create new view objects (UIWebView in your case) and add them to the view hierarchy in the "viewWillAppear:“ method of a view controller. This method is called whenever the view will become visible, and if this view controller is pushed in and out within a navigation controller, the view controller can easily become visible and hidden multiple times, while the controller itself is only created once. So you may end up in creating multiple UIWebView objects, but you only want to create one. So usually it is a better idea to create or customize your view hierarchy within the "loadView“ (creating the view hierarchy programmatically) or "didLoadView" (loading the view hierarchy from a NIB/XIB file) methods of the view controller.

I’d suggest that you start with some basics: You need to understand how view controllers work and how they can interact. Start to play with a UINavigationController and learn how to push and pull other view controllers, look at the methods „loadView“, „viewDidLoad“, „viewWillAppear:“, „viewDidAppear:“ „viewWillDisappear:“ etc, and learn when these are called.