Прокрутите UITableView вверх, коснувшись строки состояния

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


person iOSDev    schedule 23.08.2011    source источник
comment
Я протестировал (iOS 8) и обнаружил, что элемент 3 из Контрольный список Зейна Класа не нужен.   -  person Marcio Fonseca    schedule 27.10.2014


Ответы (9)


Вы получаете это бесплатно, но вы должны проверить, что атрибут scrollsToTop вашего UITableView равен ДА.

Когда это НЕ работает, это когда у вас есть объект UIScrollView (или класс-потомок, например UITextView), встроенный в другой класс UIScrollView (например, UITableView). В этом случае установите для scrollsToTop во встроенном классе UIScrollView значение NO. Тогда будет работать поведение касания строки состояния.

person Mark Granoff    schedule 23.08.2011
comment
Я пробовал то, что вы предлагаете, - установив для встроенного scrollview scrollsToTop значение NO, - но нажатие на строку состояния по-прежнему не приводит к прокрутке верхней прокрутки вверх. - person CharlieMezak; 21.10.2011
comment
Это прекрасно работает. @CharlieMezak, возможно, у вас есть более одного встроенного режима прокрутки на экране. Все они должны иметь значение NO, за исключением представления прокрутки наверху иерархии представлений. - person imnk; 16.04.2013
comment
В моем случае у меня было несколько горизонтально прокручиваемых представлений коллекции в моем вертикально прокручиваемом табличном представлении, установив scrollsToTop на NO для всех работающих представлений коллекции. Кажется нелогичным, но это сработало! - person Chris Wagner; 03.10.2013
comment
@CharlieMezak обратите внимание, что scrollsToTop = NO правило должно применяться ко всем представлениям в окне. Например, если у вас есть боковое меню. - person vokilam; 31.10.2013
comment
Спасибо! Мне это тоже помогло. Установив scrollsToTop = YES для моего tableview и моего customTableViewCell TextView, я установил его в NO. - person Jenn Eve; 17.02.2014
comment
Это происходило в моем UICollectionView. У меня был UIScrollView с боковой прокруткой внутри каждого UICollectionViewCell. Установка scrollsToTop = NO для scrollView ячейки устранила проблему. Спасибо - person RyanG; 17.10.2014
comment
Как это понять, спасибо! - person Rick van der Linde; 12.01.2016
comment
Это перестало работать для iOS9. Можете дать мне взломать для этого. - person Faisal Shaikh; 09.06.2016
comment
О, я думаю, что нет, @FaisalShaikh. Я предлагаю внимательно прочитать документацию для scrollsToTop. Убедитесь, что только для класса прокрутки (или потомка), который вы хотите прокрутить вверх при касании строки состояния, scrollsToTop установлено значение YES. Для любых других представлений прокрутки, встроенных в ваше основное представление прокрутки, scrollsToTop должно быть установлено значение NO. Если для нескольких видов прокрутки scrollsToTop установлено значение YES, этот жест игнорируется. - person Mark Granoff; 09.06.2016
comment
На моем экране строка состояния скрыта. Есть ли обходной путь для этого? - person AsifHabib; 03.11.2016
comment
@AsifHabib Я думаю, вам придется реализовать свой собственный распознаватель жестов касания в видимом виде, чтобы обнаруживать касание в верхней части экрана, а затем в коде заставлять ваш контент прокручиваться вверх. - person Mark Granoff; 03.11.2016

Если вы пришли из Google и вам нужен полный контрольный список:

  1. Убедитесь, что вы установили scrollsToTop = YES (согласно предложению Марка) в вашем UITableView
  2. Убедитесь, что вы установили scrollsToTop = NO для всех ДРУГИХ UITableViews / UIScrollViews / UITextViews в вашем окне, чтобы они не перехватывали щелчок. Я обнаружил, что много раз распечатываю все представления в моем окне, чтобы отладить это ...
  3. Убедитесь, что ваше табличное представление находится в 0/0 (координаты x / y) в окне - так система знает, что она должна передать сообщение
person Zane Claes    schedule 10.04.2013
comment
Что, если он находится в контроллере дочернего представления, который помещает его в окно ниже 0,0? - person shim; 28.06.2013
comment
Это было полезно, когда вы используете несколько uiwebviews, поскольку вам нужно установить для свойств scrollstotop неактивных веб-представлений значение NO. - person Matthew Hui; 12.07.2013
comment
Спасибо за этот полный контрольный список. Искал мой код для UITextView и нашел тот, который вызывает проблемы. - person werm098; 18.03.2014
comment
Как спросил @shim - @ Zane / @ Kyle - что, если он находится в контроллере дочернего представления, который помещает его ниже 0,0 в пределах окна? - person ofer2980; 04.10.2015

Используя информацию, приведенную в других ответах, я добавил в свой UITableViewController следующий код, чтобы заставить его работать:

- (void)viewDidLoad
{
    [super viewDidLoad];

    for (UITextView *view in self.view.subviews) {
        if ([view isKindOfClass:[UITextView class]]) {
            view.scrollsToTop = NO;
        }
    }

    self.tableView.scrollsToTop = YES;
}

Это просматривает все представления в иерархии UITableViewController и отключает scrollsToTop для всех UITextView, которые перехватывали событие касания. Затем убедитесь, что tableView все еще будет получать касание.

Вы можете изменить это, чтобы перебирать другие UITableViews / UIScrollViews / UITextViews, которые также могут перехватывать.

Надеюсь это поможет!

person Brandon Roberts    schedule 07.02.2014
comment
На самом деле вы можете просто изменить UITextView на UIScrollView в своем коде, и он перехватит все UITableView и UITextView, поскольку они оба являются подклассами UIScrollView. - person bdmontz; 15.06.2015

У меня была та же проблема, но я исправил ее, выполнив следующие действия:

  1. Установите scrollsToTop = YES для просмотра таблицы, которую вы хотите прокрутить вверх.
  2. установите scrollsToTop = NO для всех других представлений таблицы или коллекции или просмотра прокрутки.
  3. Если какая-либо из ваших ячеек tableview имеет представление коллекции. Убедитесь, что вы установили scrollsToTop в NO для представления коллекции.

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

person iOS Developer    schedule 27.11.2015
comment
Вызов addChildViewController() был недостающей частью. Спасибо! - person Pahnev; 16.03.2018

Я знаю, что это довольно старый, но надеюсь, что это может помочь. Следуя тому, что сказал @MarkGranoff, scrollsToTop не работает, если более чем для одного UIScrollView или его подклассов установлено значение YES (значение по умолчанию), вероятно, стоит проверить работоспособность, чтобы проверить, кто на самом деле испортил это поведение. Приведенный ниже простой метод перебирает подпредставления вашего представления и регистрирует значение scrollsToTop для всех UIScrollView в вашем представлении. Желательно вызывать в вашем методе viewDidAppear.

- (void)checkForScrollViewInView:(UIView *)view {
    for (UIView *subview in [view subviews]) {
        if ([subview isKindOfClass:[UIScrollView class]]) {
            NSLog(@"scrollsToTop enabled: %i in scroll view %@", ((UIScrollView *)subview).scrollsToTop, subview);
        }
        if (subview.subviews.count > 0) {
            [self checkForScrollViewInView:subview];
        }
    }
}

На самом деле это всего лишь отладочный код. Как только вы найдете значение scrollsToTop для каждого из подклассов UIScrollView, просто убедитесь, что только для одного установлено значение YES.

person DennyLou    schedule 21.08.2015

Как сказал Марк, у вас может быть только один подкласс UIScrollView (обычно табличное представление), у которого для свойства scrollsToTop установлено значение TRUE. Вероятно, у вас есть другие, обычно UITextView в вашем представлении. Просто установите для их свойства scrollsToTop значение FALSE, и все готово.

person George    schedule 02.11.2013
comment
Это была моя проблема, у меня было 2 вида таблиц на одном экране, каждый с выходом, поэтому простая установка одного из них на false помогло мне, спасибо! - person Stuart P.; 17.11.2015

В заголовочном файле UIScrollView:

// Когда пользователь касается строки состояния, вид прокрутки под касанием, ближайшим к строке состояния, будет прокручен вверх, но только если его свойство scrollsToTop имеет значение YES, его делегат не возвращает NO из shouldScrollViewScrollToTop, и это еще не наверху. // На iPhone мы выполняем этот жест, только если есть одно экранное представление прокрутки с scrollsToTop == YES. Если найдено более одного, прокрутка не будет.

person foskon    schedule 26.08.2016

Например, если у вас есть представление таблицы и прокрутка, как теги, подобные этому

введите описание изображения здесь

вы должны сделать что-то подобное в viewDidLoad

self.tableView.scrollsToTop = true
self.tagsView.scrollsToTop = false
person Abo3atef    schedule 03.12.2016

Может быть загружено несколько потомков UIScrollView, например: наличие UIPageViewcontroller на каждой странице, содержащей UITableViews.

Свойство scrollsToTop по умолчанию имеет значение true.

Таким образом, помимо обработки вложенного свойства scrollsToTop UIScrollViews, вы должны сделать следующее:

//When the view is loaded disable scrollsToTop, this view may not be the visible one
override func viewDidLoad() {
    super.viewDidLoad()
    ...
    tableView.scrollsToTop = false
}

//Now it's time to enable scrolling, the view is guaranteed to be visible
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    tableView.scrollsToTop = true
}

//Do not forget to disable scrollsToTop, making other visible UIScrollView descendant be able to be scrolled to top
override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    self.tableView.scrollsToTop = false
}

Таким образом, только для scrollsToTop UITableView верхнего уровня будет установлено значение true.

person Géza Mikló    schedule 09.03.2018