0

У меня есть подклассу UIScrollView, и у меня есть два экземпляра MyScrollView каждый в своем собственном контроллере представления, причем сегментированный контроллер переключается между ними. Оба диспетчера представлений добавляются как дочерние контроллеры в виде основного контейнера. Они переключаются путем простого скрытия/отображения представлений контроллера просмотра и вызова методов отображения/исчезновения вида на каждом контроллере в правильное время.Подкласс UIScrollView прекращает замедление

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

Моя проблема довольно тонок, показана, как например: -

  • запуска приложение
  • нагрузки вида контроллера в представление контейнера, который загружает MyScrollView экземпляра 1
  • крана сегментированного контроллера
  • скрыть контроллер вида A вид
  • контроллер вида загрузки B в конт Инер вид, который загружает MyScrollView экземпляра 2
  • крана сегментирован контроллер вида
  • скрыть вид контроллер Б
  • показать вид контроллера, который показывает MyScrollView экземпляра 1

  • Теперь, когда я прокручиваю любого экземпляр MyScrollView, он резко останавливается без замедления.

Когда я подключить делегата и добавить точки останова, я вижу, что scrollViewWillEndDragging:withVelocity:targetContentOffset: называется, как и ожидалось, но следующий вызов scrollViewDidEndDragging:willDecelerate: имеет замедлиться аргумент как NO. Проверка назад, это было YES в первых двух экземплярах (т. Е. Когда scrollviews были только что загружены).

Это, кажется, «липкая» ошибка - как только это произошло, она не исчезнет, ​​пока я не перезагружу прокрутку. Это случается с обоими прокрутками (они являются одним и тем же классом), и, похоже, это нужно показывать дважды. На втором показе прокрутка больше не будет замедляться.

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

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

EDIT

Я просто попытался удалить Scrollview из контроллера представления B, и проблема все еще существует. Поэтому похоже, что это скрывает/показывает MyScrollView, что вызывает проблему, а не любое взаимодействие между двумя списками прокрутки или их делегатами.

ответ

0

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

В моем подклассе у меня есть свойство active для обработки активации/деактивации сетки (в основном, сетка может игнорировать любые глобальные уведомления об интерфейсе пользовательского интерфейса или отложенные сетевые ответы и т. Д., Если они были скрыты). Сеттер выглядел следующим образом: -

- (void)setActive:(BOOL)active 
{ 
    if (_active != active) 
    { 
     _active = active; 

     if (_active) 
     { 
      NSLog(@"enabling notifications for grid %@", self); 
      [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(cellSelected:) name:kABIDataGridViewCellSelectedNotification object:nil]; 
      [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(headerCellSelected:) name:kABIDataGridViewHeaderCellSelectedNotification object:nil]; 
     } 
     else 
     { 
      NSLog(@"disabling notifications for grid %@", self); 
      // ** BUG HERE ** 
      [[NSNotificationCenter defaultCenter] removeObserver:self]; 
     } 

    } 
} 

кажется, что UIScrollView должна использовать некоторые внутренние NSNotifications для обработки замедления, поскольку удаление всех уведомлений скрытия сетки вызвала странное поведение. Замена ошибочной строки правильными строками ниже фиксированной.

// Important to remove only the notifications we registered, otherwise we can cause weird scrolling behavious because UIScrollView must 
    // use notifications internally. 
    [[NSNotificationCenter defaultCenter] removeObserver:self name:kABIDataGridViewCellSelectedNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] removeObserver:self name:kABIDataGridViewHeaderCellSelectedNotification object:nil]; 

Конечно, это более правильный способ отмены уведомлений. Многие разработчики iOS находят, что всегда легко отменить все, когда исчезает представление, поскольку вам не нужно отслеживать каждое уведомление, которое вы используете. Но когда подклассификация, не принимайте ничего!

Смежные вопросы