1

I'm debugging a custom UIViewController subclass, which wraps a UIWebView so that we can handle custom URLs.

I seem to have no problem adding the relevant views to the hierarchy, but when I call loadRequest: on the webview, it displays nothing. It seems as though it is not even attempting to execute the request, either - my subclass is setting itself as the UIWebView's delegate, but is not receiving any delegate callbacks from it, not even webViewDidStartLoad or shouldStartLoadWithRequest (!). What could be causing this?

The following is the relevant code from my class:

- (void)viewDidLoad {
    [super viewDidLoad];

    // add the webview
    m_webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 300, 400)];
    m_webView.delegate = self;
    m_webView.dataDetectorTypes = UIDataDetectorTypeNone;

    // adding a border to see if the view is visible onscreen
    [[m_webView layer] setBorderColor:[[UIColor darkGrayColor] CGColor]];
    [[m_webView layer] setBorderWidth:50];

    [self.view addSubview:m_webView];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:YES];

    NSURLRequest *request = [NSURLRequest requestFromUrl:[NSURL urlFromString:@"http://www.google.com"]];
    [self.m_webView loadRequest:request];
    NSLog(@"Loading URL: %@ in view: %@; delegate set as %@", @"http://www.google.com", m_webView, m_webView.delegate);
    NSLog(@"WebView is %@", self.m_webView.loading ? @"loading" : @"not loading");

}

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    NSLog(@"Loading URL of type %@, relative = %@", [[request URL] scheme], [[request URL] relativeString]);
    return YES;
}

- (void)webViewDidStartLoad:(UIWebView *)webView {
    NSLog(@"Started");
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
    NSLog(@"Failed, error %@", error);
}

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    NSLog(@"Finished");
    [self finishedReloading];
}

And the code from the controller for the parent view, which tries to add an instance of this one (currently situated in that controller's viewDidLoad method):

ZUIWebViewController *testWebView = [[[ZUIWebViewController alloc] initWithAddress:@"deal/recentDrops"] autorelease];
[m_scrollView addSubview:testWebView.view];
[testWebView viewWillAppear:YES];
NSLog(@"Added webview");

The result when I run this is:

Loading URL: http://www.google.com in view: <UIWebView: 0x1114eb30; frame = (0 0; 320 480); layer = <CALayer: 0x1114eb90>>; delegate set as <ZUIWebViewController: 0x1114d7a0>
Webview is not loading
Added webview

The view hierarchy after the "Added webview" message is:

(lldb) po [m_scrollView recursiveDescription]
(id) $1 = 0x0a634b00 <UIView: 0xbba3430; frame = (0 20; 320 460); autoresize = W+H; layer = <CALayer: 0xbba3840>>
   | <UIImageView: 0xbba3490; frame = (0 0; 320 480); userInteractionEnabled = NO; layer = <CALayer: 0xbba3940>>
   | <UIScrollView: 0xbba4390; frame = (0 0; 320 480); clipsToBounds = YES; gestureRecognizers = <NSArray: 0xbba4680>; layer = <CALayer: 0xbba4560>; contentOffset: {0, 0}>
   |    | <UIWebView: 0xbba4840; frame = (0 0; 320 480); layer = <CALayer: 0xbba48a0>>
   |    |    | <_UIWebViewScrollView: 0xbba6b70; frame = (0 0; 320 480); clipsToBounds = YES; autoresize = H; gestureRecognizers = <NSArray: 0xbba6f40>; layer = <CALayer: 0xbba6da0>; contentOffset: {0, 0}>
   |    |    |    | <UIImageView: 0xbba7860; frame = (0 0; 54 54); transform = [-1, 0, -0, -1, 0, 0]; alpha = 0; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0xbba78c0>>
   |    |    |    | <UIImageView: 0xbba77d0; frame = (0 0; 54 54); transform = [0, 1, -1, 0, 0, 0]; alpha = 0; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0xbba7830>>
   |    |    |    | <UIImageView: 0xbba7740; frame = (0 0; 54 54); transform = [0, -1, 1, 0, 0, 0]; alpha = 0; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0xbba77a0>>
   |    |    |    | <UIImageView: 0xbba76b0; frame = (0 0; 54 54); alpha = 0; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0xbba7710>>
   |    |    |    | <UIImageView: 0xbba7620; frame = (-14.5 14.5; 30 1); transform = [0, 1, -1, 0, 0, 0]; alpha = 0; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0xbba7680>>
   |    |    |    | <UIImageView: 0xbba7590; frame = (-14.5 14.5; 30 1); transform = [0, -1, 1, 0, 0, 0]; alpha = 0; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0xbba75f0>>
   |    |    |    | <UIImageView: 0xbba7500; frame = (0 0; 1 30); transform = [-1, 0, -0, -1, 0, 0]; alpha = 0; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0xbba7560>>
   |    |    |    | <UIImageView: 0xbba7470; frame = (0 0; 1 30); alpha = 0; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0xbba74d0>>
   |    |    |    | <UIImageView: 0xbba73e0; frame = (0 450; 320 30); alpha = 0; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0xbba7440>>
   |    |    |    | <UIImageView: 0xbba7380; frame = (0 0; 320 30); transform = [-1, 0, -0, -1, 0, 0]; alpha = 0; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0xbba72e0>>
   |    |    |    | <UIWebBrowserView: 0x13baa200; frame = (0 0; 320 480); gestureRecognizers = <NSArray: 0xbba5d50>; layer = <UIWebLayer: 0xbba4930>>
   |    |    |    |    | <TileHostLayer: 0xbba4a00> (layer)
   |    |    |    |    |    | <TileLayer: 0xbba7ef0> (layer)

So it doesn't appear that there's anything in front of the UIWebView I'm trying to display.

What could be causing this, and are there any further steps I should be taking to debug?

Cezar
  • 55,636
  • 19
  • 86
  • 87
Arkaaito
  • 7,347
  • 3
  • 39
  • 56
  • Why are you calling `[testView viewWillAppear:YES]` manually? It should be called automatically when `testView` appears. It may be stupid to ask, but is there a possibility that m_scrollView is not initiated (nil)? – barley Sep 28 '12 at 23:57
  • This seems a little odd to me too, but apparently viewWillAppear does not get called when views are created programmatically in certain contexts (see the answer on http://stackoverflow.com/questions/895713/viewdidload-gets-called-viewwillappear-does-not-get-called-view-does-not-appea). Looking at this log output again I see I pulled the output from the wrong run - gah! I'll edit it, but the short version is that yes, I've confirmed m_scrollView is displayed. – Arkaaito Sep 29 '12 at 00:00
  • You have this log statement: `NSLog(@"Loading URL: %@ in view: %@; delegate set as %@", @"http://www.google.com", m_webView, m_webView.delegate);`. What happens when you replace the hard-coded google.com with `[request URL]`? Also, where is `requestFromUrl` defined? Could you share its implementation? – Carl Veazey Sep 29 '12 at 00:31
  • Feels to me that even `viewDidLoad` is not being called. See that the size of the frame is different in the log compared to the one specified in there. That actually explains that the delegate methods are not called because the delegate is not set. – barley Sep 29 '12 at 01:03

1 Answers1

0

You are loading webview in viewWillAppear and later in viewDidLoad (which is called after viewWillAppear) you are creating a webview. which should be other way around. create a webview and then load request.

Just keep everything in either viewDidLoad or view will appear, create webview, and load request. this should work fine.

user431791
  • 341
  • 2
  • 17
  • 2
    Just tested this because it seemed wrong and ViewDidLoad is called first, then ViewWillAppear then ViewDidAppear. – Conor Nov 28 '13 at 17:22