views:

913

answers:

1

It looks like a problem which could have simple solution, but I haven't found anything what could lead the way to it. I'm using UIWebView inside of UIScrollView and tapping on statusBar (to scroll content to top) is not working.

I've made simple test application to see if it's really UIWebViews fault. And it really is.

//  scrolls to top on status bar tap 
UIScrollView *sv = [[UIScrollView alloc] init];
sv.frame = CGRectMake(0, 0, 320, 480);
sv.contentSize = CGSizeMake(320, 1200);
[self.view addSubview:sv];

// doesn't scroll
UIScrollView *sv = [[UIScrollView alloc] init];
sv.frame = CGRectMake(0, 0, 320, 480);
sv.contentSize = CGSizeMake(320, 1200);

UIWebView *wv = [[UIWebView alloc] init];
wv.frame = CGRectMake(0, 0, 320, 100);
[sv addSubview:wv]; 

[self.view addSubview:sv];

So, I think maybe there's something I could disable to make UIWebView not to mess with scrollToTop? Or some kind of workaround also would be nice.

Any ideas?

+3  A: 

I ran into this last night until I finally found the answer buried in a comment to a comment. The idea of that original post is that when you add the UIWebView to your UIScrollingView, you use the following:

- (void) ensureScrollsToTop: (UIView*) ensureView {
    ((UIScrollView *)[[webView subviews] objectAtIndex:0]).scrollsToTop = NO;
}

This seemed fishy to me since the first sub-view of a UIWebView claims to be a UIScroller which is not a subclass of UIScrollView. However, since UIScroller supports the scrollsToTop property, the cast just gives us a way past the compiler warning:

Class List:
    Class = UIScroller
    Class = UIView
    Class = UIResponder
    Class = NSObject
Supported Methods:
    ...
    Method _scrollToTop
    Method setScrollsToTop:
    Method scrollsToTop
    ...
Supported Properties:
    Property scrollsToTop

EDIT: Just another quick note about where this actually needs to occur: in the webViewDidFinishLoad callback. Calling it on UIWebView construction isn't good enough because at that time the UIWebView hasn't created it's child views yet, which are the ones causing the problem:

- (void)webViewDidFinishLoad:(UIWebView *) wv {    
    [self ensureScrollsToTop: wv];
}
nivekastoreth
Thanks nivekastoreth, this was bugging me. I just want to point out that you're missing a '(' in ensureScrollsToTop and I want to remind anyone else who finds this to set the delegate of the webview so webViewDidFinishLoad gets called.
Rob Lourens
this works, but you probably meant: ((UIScrollView *)[[webView subviews] objectAtIndex:0]).scrollsToTop = YES;
nc