Смещение содержимого UIScrollView сбрасывается - PullRequest
4 голосов
/ 14 февраля 2012

Я долгое время боролся с проблемой с UIScrollView.

У меня есть UIScrollVIew, который содержит UITextView в качестве подпредставления.Когда я выбираю текстовое представление, появляется клавиатура.Я хочу изменить размер текстового представления, чтобы оно вписывалось точно в доступное пространство, а также прокручивать вид прокрутки так, чтобы текстовое представление располагалось точно в видимом пространстве (не скрывалось клавиатурой).

Когда клавиатураПоявляется, я вызываю метод, который вычисляет соответствующий размер для текстового представления, а затем выполняет следующий код:

[UIView animateWithDuration:0.3 
                 animations:^
 { 
     self.textView.frame = frame;
 }  
 ];

[self.scrollView setContentOffset:CGPointMake(0,frame.origin.y) animated:YES];

(здесь frame - это соответствующий кадр для текстового представления).

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

После долгих испытаний я наконец понял, что после завершения анимации представление прокрутки снова автоматически прокручивается.

Этот код работает:

UIView animateWithDuration:0.3 
                 animations:^
 { 
     self.textView.frame = frame;
 }
 completion:^(BOOL finished) {
     [self.scrollView setContentOffset:CGPointMake(0, frame.origin.y) animated:YES];
 }
 ];

, но выглядит странно, потому что представление прокрутки прокручивается в неправильную позицию, а затем в правую.

Кто-нибудь знает, как я могу запретить представлению прокрутки изменять смещение содержимого, когда рамка текстового представления завершает анимацию?

Я тестирую с использованием iOS 5.0.


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

- (void)keyboardDidShow:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];

    // Get the height of the keyboard
    CGRect kbRect = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
    kbRect = [self.view convertRect:kbRect fromView:nil];
    CGSize kbSize = kbRect.size;

    // Adjust the height of the text view to fit in the visible view
    CGRect frame = self.textView.frame;
    int visibleHeight = self.view.frame.size.height;
    visibleHeight -= kbSize.height;
    frame.size.height = visibleHeight;

    // Get the new scroll view content size
    CGSize contentSize = self.scrollView.contentSize;
    contentSize.height = contentSize.height - self.textView.frame.size.height + frame.size.height;

    [UIView animateWithDuration:0.1 
                     animations:^
     { 
         self.textView.frame = frame;
         // Note that the scroll view content size needs to be reset, or the scroll view
         // may automatically scroll to a new position after the animation is complete.
         self.scrollView.contentSize = contentSize;
         [self.scrollView setContentOffset:CGPointMake(0, frame.origin.y) animated:YES];
     }     
     ];

    // Turn off scrolling in scroll view
    self.scrollView.scrollEnabled = NO;
}

// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    // Update the view layout
    [UIView animateWithDuration:0.3 animations:^
     {
         self.scrollView.contentOffset = CGPointZero;
         [self updateViewLayout];
     }
     ];

    // Turn on scrolling in the scroll view
    self.scrollView.scrollEnabled = YES;
}

([self updateViewLayout] - это метод, который возвращает представление текста на правильную высоту и сбрасывает представление прокруткиразмер контента, а также убедитесь, что все остальные подпредставления правильно расположены).

Ответы [ 4 ]

3 голосов
/ 29 марта 2013

Полагаю, у меня тоже было нечто подобное.Я хотел, чтобы мой горизонтальный UIScrollView вернулся к своему исходному смещению (0,0), и каждый раз, когда я возвращался к нему, он отключался всего на пару пикселей, но как только кто-то коснулся скролл-просмотра, он продолжал бы и заканчиваланимация (почти как отставание в видеоигре).

Из-за этого я попытался поместить его в GCD в качестве основной очереди, и после этого он работал отлично.Вот код:

- (void)setPageZero{
       dispatch_async(dispatch_get_main_queue(), ^{
       [UIView animateWithDuration:1.0f
                delay:0 options:UIViewAnimationOptionCurveEaseInOut
                animations:^{
                     [self.scrollView setContentOffset:CGPointMake(0, self.scrollView.frame.origin.y) animated:YES];
                 }
           completion:^(BOOL finished) {}];
       });
}

Что он делает в основном, так это то, что он помещает анимацию в основную очередь (что-то вроде супермагистрали в CPU / GPU) и устанавливает приоритет над другими вещами!

Надеюсь, это поможет будущим читателям!

3 голосов
/ 15 февраля 2012

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

[self.scrollView setContentOffset:CGPointMake(0, frame.origin.y) animated:YES];

Если вам необходимо прокрутить представление с определенной скоростью, затем вручную отрегулируйте смещение содержимого в блоке анимации. (Я не проверял это, вы можете настроитьфлаг анимации или шаг за шагом сдвигайте содержимое на один пиксель за раз, если это не работает)

[UIView animateWithDuration:0.3f 
             animations:^{ 
  [self.scrollView setContentOffset:CGPointMake(0, frame.origin.y) animated:YES];
} ];
2 голосов
/ 18 июля 2012

У меня похожая проблема.В основном у меня есть представление прокрутки с тремя страницами, каждая из которых содержит собственный класс UIView.Пользовательский класс UIView содержит изображение и ряд наложенных изображений, содержащих информацию об изображении.Представления с наложением содержат несколько полей UITextView.

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

Если я создаю UITextField объекты и отключаю прокрутку следующим образом:

UITextView* view = [[UITextView alloc]
                    initWithFrame:CGRectMake(position.x,position.y,width,height)];
view.editable = NO;  
view.scrollEnabled = NO;

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

Однако, если я закомментирую код для отключения прокрутки

UITextView* view = [[UITextView alloc]
                    initWithFrame:CGRectMake(position.x,position.y,width,height)];
view.editable = NO;  
// view.scrollEnabled = NO;

это изменение положения не происходит, и прокрутка работает как ожидалось.

0 голосов
/ 03 мая 2016

Полный взлом: может улучшить проблему сброса:

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{        
        [self setContentOffset:self.contentOffset animated:NO];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...