UIWebView прокручивает только фокус ввода iOS 6

Я загружаю UIWebView в модальном режиме. Веб-страница имеет некоторые входы, которые работают точно так, как предполагалось в iOS 5. Однако в iOS 6, когда вход становится фокусом, клавиатура выполняет автоматическое "центрирование" формы, даже если входы имеют достаточно места для показа выше клавиатура. Поскольку некоторые из входов находятся в верхней части страницы, это заставляет их не смотреть, поэтому пользователь не может видеть, что они печатают. Прокрутка назад для просмотра входов приводит к тому, что клавиатура перестает работать до тех пор, пока не будет отклонена и не будет перефокусировать вход (в свою очередь, прокручивая его снова). Является ли это ожидаемым поведением в iOS 6? Есть ли способ удерживать веб-просмотр от прокрутки, когда вход получает фокус (например, как работает iOS 5)?

Ответы

Ответ 1

Не зная внутренней работы вашего кода, я постараюсь помочь как можно больше. Если ничего другого, я надеюсь дать немного еды для размышлений. Вы задали два вопроса:

Ожидается ли поведение в iOS6?

То, что вы видите, довольно странно. Странно, что webView центрирует форму, а не центрирует поле ввода. И это определенно не должно заставлять активное поле ввода прокручиваться вне поля зрения. Кроме того, клавиатура, похоже, перестает работать, что довольно странно. Однако ожидается, что в iOS 5 и 6 будет наблюдаться различное поведение в отношении прокрутки webView. Как вы сказали, iOS 5 прокручивает входной экран, пока iOS6 помещает его в центр.

Можно ли прокручивать веб-просмотр, когда фокус ввода увеличивается (например, как работает iOS 5)?

Да. Я предоставляю код, чтобы сделать это ниже, а именно, чтобы остановить прокрутку webView. Если это именно то, что вы хотите сделать, тогда здорово. Тем не менее, остановка прокрутки webView не совпадает с тем же поведением, что и iOS5. Тем не менее, я хотел дать вам этот вариант, как вы его просили.

#import "ViewController.h"

@interface ViewController () <UIScrollViewDelegate> {
    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

Если требуется согласованное поведение прокрутки...

Мне потребовалось некоторое время, чтобы скопировать эту модификацию прокрутки. Вы можете использовать его в качестве ссылки при создании собственного поведения прокрутки, которое согласовано между iOS 5 и 6. В этом коде: Когда пользователь нажимает на текстовое поле ввода на веб-странице, код останавливает поведение прокрутки по умолчанию, сохраняя прокрутку страницы до текущей позиции. К сожалению, нет способа отменить прокрутку, но вам придется переопределить свитки. Когда прокрутка по умолчанию была "подавлена", она получает позицию активного окна ввода и прокручивается до этой позиции. Это положит активное поле ввода в верхней части экрана. Вы можете изменить это в соответствии с вашими предпочтениями. Например, вы можете использовать [UIScrollView scrollRectToVisible], чтобы сделать его более похожим на iOS5.

#import "ViewController.h"

@interface ViewController () <UIScrollViewDelegate> {
    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

Если бы этот код помог вам, вам было бы очень приятно вознаградить щедрость мне. Я был бы смиренно благодарен.

Ответ 2

Обходной путь может привести к отключению прокрутки в этом UIWebView:

UIScrollView *scrollView = webView.scrollView;
[scrollview setScrollEnabled:NO];
[scrollView bounces:NO];

Другим может быть настройка UIEdgeInsets этого scrollView, но я мало знаю об этом.

Я думаю, что это стандартное поведение в iOS 5 и 6 для прокрутки, чтобы сделать поле ввода только поверх клавиатуры (как это делает Safari).

Ответ 3

Проверенный ответ на этот пост имеет ваш ответ: Как заставить UITextField двигаться вверх, когда присутствует клавиатура?

Короче говоря, вам нужно переместить представление, содержащее входы, которые вытесняются из вида. Сообщение также содержит пример кода о том, как это сделать.

Надеюсь, что это поможет.