hi,
I've used stringByEvaluatingJavaScriptFromString plus moving UIWebView origin.
Design overview: I had a set of controls(UIImage in this example) above(I mean frame.origin.y) UIWebView. So, layout was:
UIView
UIScrollView
UIImageView
UIWebView
Since UIWebView doesn't support scrolling in such hierarchy I've rearrange it like:
UIView
UIScrollView
UIImageView
UIWebView
My view controller is delegate for UIWebViewDelegate and UIScrollViewDelegate.
Then,
- (void)viewDidLoad
{
// set delegates
self.scrollView.delegate = self;
self.webView.delegate = self;
// store original UIWebView position in ivar
webViewPosY = self.webView.frame.origin.y;
// load html into UIWebView
[self.webView loadHTMLString:someHTML baseURL:nil];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
// get UIWebView size and store in ivar
webSize = [self.webView sizeThatFits:CGSizeMake(1.0,1.0)];
// set proper content height for UIScrollView
CGSize contentSize = self.scrollView.contentSize;
contentSize.height = webViewPosY + webSize.height;
self.scrollView.contentSize = contentSize;
// set UIWebView's frame height same as UIScrollView has
CGRect wf = self.webView.frame;
wf.size.height = self.scrollView.frame.size.height;
self.webView.frame = wf;
}
// scrolling logic:
// 1. if origin of UIWebView > 0 then move UIWebView itself
// 2. if origin of UIWebView == 0 then scroll with javascript
// 3. if origin is 0 and whole html is scrolled then move UIWebView again(this happens to support scroll "bouncing", or if you have some views below UIWebView
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat scrollPosY = self.scrollView.contentOffset.y;
// (1) and (2) ifs
// how much to move UIWebView
CGFloat scrollOriginY = (scrollPosY >= webViewPosY) ? webViewPosY : scrollPosY;
// how much to scroll via JS
CGFloat scrollJSY = scrollPosY - scrollOriginY;
// (3) if
if ( scrollPosY > (webSize.height - scrollViewSize.height + webViewPosY ) )
scrollOriginY += scrollPosY - (webSize.height - scrollViewSize.height + webViewPosY);
// scroll with JS
[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"document.body.scrollTop = %f;", scrollJSY]];
// move UIWebView itself
CGRect wf = self.webView.frame;
wf.origin.y = webViewPosY - scrollOriginY;
self.webView.frame = wf;
}
This works just fine for me.