UIWebView scrolling down on input focus iOS 6 only

后端 未结 3 1588
面向向阳花
面向向阳花 2021-02-02 15:45

I\'m loading a UIWebView in a modal. The web page has some inputs that work exactly as intended in iOS 5. However in iOS 6, anytime an input gets focus, the keyboard is doing it

3条回答
  •  不知归路
    2021-02-02 16:12

    Without knowing the inner workings of your code, I'm going to try to help as much as I can. If nothing else, I hope to provide some food for thought. You asked two questions:

    Is it expected behavior in iOS6?

    What you're seeing is quite odd for sure. It's strange that the webView is centering the form rather than centering the input field. And it should definitely not cause the active input field to scroll out of view. Furthermore, the keyboard seems to stop working, which is quite odd. However, it is expected to see different behavior in iOS 5 and 6 with regards to the webView scrolling. As you said, iOS 5 scrolls the inputField into view while iOS6 puts it in center.

    Is there any way to keep the webview from scrolling when an input gains focus (like how iOS 5 works)?

    Yes. I provide code to do just this below -- namely to stop the webView from scrolling. If that is exactly what you want to do, then great. However, stopping the webView from scrolling is not the same as getting the same behavior as iOS5. Still, I wanted to give you this option as you requested it.

    #import "ViewController.h"
    
    @interface ViewController ()  {
        CGPoint origin;
    }
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://www.google.com"]];
        [self.webView loadRequest:request];
        self.webView.scrollView.delegate = self;
    
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(keyboardWillShow)
                                                     name:UIKeyboardWillShowNotification
                                                   object:nil];
    
        // NOTE THAT SIMPLY DISABLING THE SCROLL WILL NOT PREVENT KEYBOARD SCROLL
        //[self.webView.scrollView setScrollEnabled:NO];
    }
    
    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    - (void)keyboardWillShow {
        NSLog(@"keyboard");
        origin = self.webView.scrollView.contentOffset;
    
    }
    
    -(void)scrollViewDidScroll:(UIScrollView *)scrollView {
        NSLog(@"scroll");
        [self.webView.scrollView setContentOffset:origin];
    }
    
    @end
    

    If you want consistent scroll behavior...

    I took some time to code up this scroll modification. You can use it as a reference in making your own scroll behavior that is consistent across iOS 5&6. In this code: When the user clicks on a text input box on a webpage, the code will stop the default scrolling behavior by keeping the page scrolled to its current position. Unfortunately, there is no way to cancel all scrolling, but rather you have to override scrolls. Once the default scrolling has been "suppressed", it gets the position of the active input box and scrolls to that position. This will put the active input box in the top of the screen. You can modify this according to your preferences. For example, you can use [UIScrollView scrollRectToVisible] to make it more like iOS5.

    #import "ViewController.h"
    
    @interface ViewController ()  {
        CGPoint origin;
        CGPoint activeElementOrigin;
        BOOL pauseScroll;
    }
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://www.google.com"]];
        [self.webView loadRequest:request];
        self.webView.scrollView.delegate = self;
    
        pauseScroll = NO;
        origin = CGPointZero;
    
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(keyboardWillShow)
                                                     name:UIKeyboardWillShowNotification
                                                   object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(keyboardDidShow)
                                                     name:UIKeyboardDidShowNotification
                                                   object:nil];
    }
    
    - (void)keyboardWillShow {
        NSLog(@"keyboard");
        pauseScroll = YES;
        origin = self.webView.scrollView.contentOffset;
    }
    
    - (void)keyboardDidShow {
        NSLog(@"keyboard DID SHOW");
        pauseScroll = NO;
        [self.webView.scrollView setContentOffset:activeElementOrigin animated:YES];
    }
    
    -(void)scrollViewDidScroll:(UIScrollView *)scrollView {
        NSLog(@"scroll");
    
        if (pauseScroll) {
            [self.webView.scrollView setContentOffset:origin animated:NO];
    
            NSString *javaScript = [NSString stringWithFormat:@"function f(){ var textField = document.activeElement; return textField.getBoundingClientRect().top; } f();"];
            NSString *textFieldRectTop = [self.webView stringByEvaluatingJavaScriptFromString:javaScript];
            activeElementOrigin = origin;
            activeElementOrigin.y = [textFieldRectTop floatValue]-10;
        }
    }
    
    
    @end
    

    If this code helped you, it would be very nice of you to reward the bounty to me. I would be humbly appreciative.

提交回复
热议问题