4
votes

I have an iPad application in which I am displaying an input form as a UIWebView in a UIPopoverController. My popover controller is sized such that it does not have to be resized when the keyboard appears.

When I tap in an input field in the UIWebView, the web view is pushed further up when the keyboard appears. It is pushed up to the point that the text field is at the top of the frame. (This is the standard behavior you see when using forms in mobile safari).

The webview does not scroll at all before the keyboard is up, but once it is, (as seen in the second image) I can scroll the webview back down to the correct position.

Because my webview is already sized correctly, I do not want this behavior. Does anyone have any suggestions on how to prevent this? (Not using a web view here is currently not an option)

Thanks!

View without keyboardView with keyboard

2
seems to me like you could do some javascript / jquery with this, so I'll edit your tags for you so you may get some answers there.Richard J. Ross III
I wondered if there could be an approach along those lines, but forget to tag it :) thanks!jmac

2 Answers

3
votes
  1. Add UIKeyboardWillShowNotification to NSNotificationCenter in viewDidLoad

    [[NSNotificationCenter defaultCenter] addObserver:self 
        selector:@selector(keyboardWillShow:) 
        name:UIKeyboardWillShowNotification object:nil];
    
  2. Implement keyboardWillShow: and readjustWebviewScroller methods

    - (void)keyboardWillShow:(NSNotification *)aNotification {
        [self performSelector:@selector(readjustWebviewScroller) withObject:nil afterDelay:0];
    }
    
    
    - (void)readjustWebviewScroller {
        _webView.scrollView.bounds = _webView.bounds;
    }
    

This does work for me.

0
votes

I'm not an Objective-C programmer (in fact I don't know Objective-C at all :-), but I needed to do this as well (in my web application running on iPad in a WebView), so with a "little" help of Google I did this:

- (void)init {
    [[NSNotificationCenter defaultCenter]
     addObserver:self
     selector:@selector(keyboardWillShow:)
     name:UIKeyboardWillShowNotification object:nil];
}

- (void)keyboardWillShow:(NSNotification *)aNotification {

    float x = self.webView.scrollView.bounds.origin.x;
    float y = self.webView.scrollView.bounds.origin.y;
    CGPoint originalOffset = CGPointMake(x, y);

    for (double p = 0.0; p < 0.1; p += 0.001) {
        [self setContentOffset:originalOffset withDelay:p];
    }
}

- (void)setContentOffset:(CGPoint)originalOffset withDelay:(double)delay {
    double delayInSeconds = delay;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        [self.webView.scrollView setContentOffset:originalOffset animated:NO];
    });
}

I know that this isn't the best solution - but it works. From the point of view of a general programming (I don't know Objective-C) i guess it may be possible to overwrite setContentOffset method of UIScrollView class and implement your own behaviour (and possibly calling a super method of a parent).