Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add controls beneath a UIWebView

What's the simplest, fastest, or otherwise (objectively) best way to add a couple of controls (e.g. some UIButtons) beneath a UIWebView?

To be clear, I'd like to display a regular scrolling UIWebView, but when scrolling reaches the bottom I'd like there to be some UIControls after the web content. I'd rather not fake it with HTML/CSS content that looks like a control; ideally they should be real controls that I can hook up to my view controller as usual.

I don't know whether it's easiest to try to do this with one big UIScrollView containing both the UIWebView and the controls (will there be scrolling conflicts between the UIScrollView and the nested UIWebView?), or with a UITableView containing the web view and controls in separate cells (will performance be terrible?), or in some other way that I haven't thought of.

Update: I don't imagine that I want the UIWebView itself to actually scroll; I thought I'd need to resize it to accommodate all of its content, disable its scrolling behaviour entirely, and then allow the user to scroll its parent view (either the UIScrollView or the UITableView) to reveal different parts of the UIWebView.

like image 892
Tom Stuart Avatar asked Jul 25 '09 08:07

Tom Stuart


1 Answers

Neither the UIScrollView nor UITableView solutions you proposed will work.

If you put the UIWebView in a UIScrollView, one or the other will intercept the scrolls and scroll its content pane, but the other will not. I'm not sure which one will, I think it would be the UIScrollView. In any case, there is no provision for the UIScrollView to scroll when you reach the end of scrolling in the UIWebView, or vice versa.

If you use a UITableView, the UIWebView will scroll inside its cell, but the UITableView won't scroll at all, or the UIWebView won't scroll at all, and the UITableView will. If you use the 'grouped' table style, it's possible that you could scroll the UIWebView and the UITableView, but it would not be the cohesive sort of experience you are looking for.

The only technique I can think of that might work is to muck around in the internals of the UIWebView and add your UIView containing buttons and whatnot to the scrolling entity used by the UIWebView. This is beyond my ken, but these header dumps will get you started. Keep in mind that if Apple notices what you're doing, they may reject your app, and additionally, the internals may change at any time, breaking your code. If you go this route, try to code it in such a way that missing functionality will cause a graceful failure.

EDIT:

With some discussion and experimenting, the OP and I have come to the conclusion that it is very possible, and there is a way to do it that doesn't rely on internals at all. That is, use an enclosing scroll view, and resize the web view once it has loaded to the full size of its own content view. This size can be found using [webView sizeThatFits:CGSizeZero].

If you did want to use UIWebView's privates to accomplish this, I have a short code example of adding a view to the UIWebView's document view, since I got it all worked out anyway :)

- (void)applicationDidFinishLaunching:(UIApplication *)application {    

    // Override point for customization after app launch 
    UIView* testView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)] autorelease];
    UIWebView* testWebView = [[[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)] autorelease];
    [testView addSubview:testWebView];
    [testWebView setDelegate:self];
    [testWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://google.com"]]];



    [window addSubview:testView];
    [window makeKeyAndVisible];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
    UIView *insert = [[[UIView alloc] initWithFrame:CGRectMake(0, [[webView _documentView] frame].size.height, 320, 40)] autorelease];
    [insert setBackgroundColor:[UIColor greenColor]];
    [[webView _documentView] addSubview:insert];
}
like image 184
Alice Isabelle Avatar answered Oct 21 '22 00:10

Alice Isabelle