Могу ли я переопределить автоматическое поведение представления прокрутки, чтобы перейти к первому респонденту? - PullRequest
9 голосов
/ 04 октября 2011

У меня есть UITextField внутри UIScrollView (несколько уровней глубиной).Я наблюдаю за UIKeyboardDidShowNotification, а также вызываю тот же код, когда я вручную изменяю первый респондент (я мог бы перейти на другое текстовое поле без мгновенного скрытия клавиатуры).В этом коде я использую scrollRectToVisible:animated:, чтобы убедиться, что UITextField является видимым.

У меня была огромная головная боль отладки, почему это было забавно, но теперь я понял, что UIScrollView автоматически гарантирует, что первый респондент находится в пределах егограницы.Я изменяю фрейм UIScrollView так, чтобы ничего не скрывалось за клавиатурой.

Однако мой код может быть немного умнее их кода, потому что я хочу показать не только UITextField, но некоторые рядомсвязанные взгляды также.Я пытаюсь показать эти взгляды, если они будут соответствовать;если не что-то еще, я стараюсь показать их как можно больше, но, по крайней мере, гарантирую, что UITextField будет видимым.Поэтому я хочу сохранить свой собственный код.

Автоматическое поведение мешает моему коду.То, что я вижу, - это представление прокрутки, аккуратно прокручивая вверх, так что нижний край моего контента становится видимым, а затем привязывается к месту, в котором мой код указал его положение.

Есть ли способ остановить выполнение UIScrollViewвозможность по умолчанию прокрутки первого респондента в представление?

Подробнее

При просмотре документации я прочитал, что они советуют изменять contentInset представления прокрутки вместо фрейма.Я изменил это и устранил непредсказуемое поведение, но это не решило эту конкретную проблему.

Я не думаю, что размещение всего кода обязательно будет таким полезным.Но вот критический вызов и значения важных свойств того времени.Я просто напишу 4 кортежа для CGRects;Я имею в виду (x, y, ширина, высота).

[scrollView scrollRectToVisible:(116.2, 71.2, 60, 243) animated:YES];

scrollView.bounds == (0, 12, 320, 361)

scrollView.contentInset == UIEdgeInsetsMake (0,0, 118, 0)

textField.frame == (112.2, 222.6, 24, 24)

преобразованы в координаты непосредственного подпредставления scrollView == (134.2, 244.6, 24,24)

преобразовано в координаты scrollView == (134.2, 244.6, 24, 24)

Таким образом, нижний край представления прокрутки действительно равен y == 243 из-за вставки.

Запрашиваемый прямоугольник расширяется до y == 314.2.

Текстовое поле расширяется до y == 268,6.

Оба выходят за пределы.scrollRectToVisible пытается исправить одну из этих проблем.Стандартное поведение UIScrollView / UITextField пытается исправить другое.Они не придумали совершенно одинаковое решение.

Ответы [ 4 ]

5 голосов
/ 13 октября 2011

Я не тестировал эту конкретную ситуацию, но мне удалось предотвратить отскок просмотра прокрутки сверху и снизу путем создания подкласса просмотра прокрутки и переопределения setContentOffset: и setContentOffset: animated :.Scrollview вызывает это при каждом движении прокрутки, поэтому я вполне уверен, что они будут вызываться при прокрутке до текстового поля.

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

В коде:

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    self.blockingTextViewScroll = YES;
}

-(void)setContentOffset:(CGPoint)contentOffset
{
    if(self.blockingTextViewScroll)
    {
        self.blockingTextViewScroll = NO;
    }
    else
    {
        [super setContentOffset:contentOffset];
    }
}


-(void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated
{
    if(self.blockingTextViewScroll)
    {
        self.blockingTextViewScroll = NO;
    }
    else
    {
        [super setContentOffset:contentOffset animated:animated];
    }
}

Если ваше текущее поведение прокрутки работает с setContentOffset: override, просто поместите его внутри блоков else (или, предпочтительно, в метод, который вы вызываете из блоков else).

2 голосов
/ 07 мая 2014

В моем проекте мне удалось добиться этого, выполнив прокрутку только после некоторой задержки.

- (void)keyboardWillShow:(NSNotification *)note
{
    NSDictionary *userInfo = note.userInfo;
    CGRect keyboardFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];

    UIEdgeInsets contentInsets = self.tableView.contentInset;
    contentInsets.bottom += keyboardFrame.size.height;

    [self.tableView setContentInset:contentInsets];
     [self performSelector:@selector(scrollToEditableCell) withObject:nil afterDelay:0];
}

Также есть другая возможность сделать ваше представление с дополнительными представлениями, чтобы быть первым респондентом и дурацким представлением прокрутки, где прокрутить.Еще не проверял.

0 голосов
/ 12 октября 2011

Попробуйте изменить автоматическое изменение размера представления на UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin. По умолчанию FlexibleTopMargin, так что, возможно, в этом причина. кстати scrollRectToVisible: использует scrollView.contentSize.

Другая вещь, которую вы можете попробовать сначала изменить размер scrollView, а затем применить изменение scrollRectToVisible:. Сначала смена фрейма, потом смена контента. (Может быть, наблюдать за клавиатурой действительно появилось событие)

0 голосов
/ 09 октября 2011

Это может оказаться бесполезным, но вы пытались установить scrollView.userInteractionEnabled в НЕТ перед вызовом scrollrectToVisible: и затем установить его обратно в ДА?Это может предотвратить автоматическую прокрутку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...