Настройка высоты UIScrollView на основе UITableView



У меня есть UIScrollView, который содержит UIView и UITableView. Моя цель-настроить высоту UIScrollView, чтобы я мог прокручивать содержимое UIScrollView до определенной точки.



Вот мой взгляд: у него есть UIView вверху и UITableView внизу.



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



Когда я прокручиваю, я хочу, чтобы UIView остановился в определенной точке, такой как:
Введите описание изображения здесь



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



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



Спасибо

606   6  

6 ответов:

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

[self.tableView setTableHeaderView:self.headerView];

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
     return self.tableViewHeader;
}

Добавьте себя в качестве UIScrollViewDelegate в UITableView и реализуйте - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView так, чтобы, если ваши представления находятся в своих начальных позициях, они делали это:

- ваш UITableView анимирует свой размер до второго состояния:

 [UIView animateWithDuration:.1f animations:^{
      CGRect theFrame = myView.frame;
      theFrame.size.height += floatOfIncreasedHeight;
      myView.frame = theFrame;
    }];

- ваш UIView оживляет его вертикальное движение

 [UIView animateWithDuration:3 delay:0 options:UIViewAnimationOptionCurveLinear animations:^(void){
        view.center = CGPointMake(view.center.x , view.center.y + floatOfVerticalMovement);
        }completion:^(BOOL Finished){ 
        view.center = CGPointMake(view.center.x , view.center.y - floatOfVerticalMovement);]

Наконец, всегда в делегате реализуйте – scrollViewDidScrollToTop:, чтобы вы знали, что можете анимировать обратно в исходное состояние (используя те же методы реверсированный).

Обновление:

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

Сделайте размер рамки прокрутки таким же большим, как ваш окончательный tableview + ваш начальный (весь) вид и поместите его на 0,0 (таким образом, его конечная часть будет скрыта за пределами экрана)

scrollview.frame = CGRectMake(0,0,tableview.frame.size.width,tableview.frame.size.height + view.frame.size.height);

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

scrollview.contentSize = CGSizeMake(scrollview.frame.size.width, tableview.frame.size.height + view.frame.size.height + floatOfViewHeightIWantOutOfTheWay);

Вы помещаете представление одно за другим в scrollview, оставляя все дополнительное пустое пространство после представления таблицы

view.frame = CGRectMake(0,0,view.frame.size.width, view.frame.size.height);

tableview.frame = CGRectMake(0,view.frame.size.height, tableview.frame.size.width, tableview.frame.size.height);

Теперь это должно просто работать, потому что так как iOS 3 вложенный scrolling поддерживается

Вы можете легко достичь этого, правильно установив размер содержимого scrollView и сохранив высоту UITableView меньше высоты вашего viewcontroller, чтобы он соответствовал нижней части верхнего UIView и UITableView...

Другой сценарий состоит в том, чтобы разделить вид сверху на 2 части. Часть, которая будет прокручиваться, и часть, которая будет видна.

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

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

Во-первых, легкая часть: подделка липкого вида. Это "представление, которое всегда присутствует при прокрутке таблицы" реализовано в виде заголовка раздела. Сделав количество секций в таблице 1, и реализуя -headerViewForSection:, можно легко сделать вид прокрутки с tableview все бесплатно (API-мудрый то есть):

- (UITableViewHeaderFooterView *)headerViewForSection:(NSInteger)section {
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0,0,320,50)];
    label.text = @"Info that was always present when scrolling the UITableView";
    label.textAlignment = UITextAlignmentCenter;
    label.backgroundColor = [UIColor colorWithRed:0.243 green:0.250 blue:0.253 alpha:1.000];
    label.textColor = UIColor.whiteColor;
    return label;
}
Наконец, самое трудное: кво. Когда таблица прокручивается, мы должны держать заголовок там липким относительно верхней части фрейма представления, что означает, что вы можете KVO contentOffset и использовать результирующее изменение значения, чтобы приблизить фрейм, к которому представление должно прилипнуть с небольшим волшебством MIN(). Предполагая, что ваш заголовок имеет высоту 44 пикселя, код ниже вычисляет соответствующее значение кадра:
CGPoint offset = [contentOffsetChange CGPointValue];
[self.tableView layoutSubviews];
self.tableView.tableHeaderView.frame = CGRectMake(0,MIN(0,offset.y),CGRectGetWidth(self.scrollView.frame),44);

Если вышеизложенное невыполнимо, SMHeadedList на самом деле имеет довольно большой и малоизвестный пример того, насколько сложным может быть реализация "двойного tableview". Эта реализация имеет дополнительное преимущество, позволяя" header "tableview прокручиваться с" main " tableview.

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

Что делать, если разбить UIView на верхнюю и нижнюю части. Внизу будет информация.
Установить UITableView.tableHeaderView = topView в viewDidLoad
и возврат bottomView в качестве заголовка раздела в методе делегата, чтобы сделать его плавающим:

(UITableViewHeaderFooterView *)headerViewForSection:(NSInteger)section
{
   return bottomView;
}

Просто с помощью UITableView можно решить вашу проблему. нет необходимости использовать другой вид прокрутки.

  1. задайте свое представление в качестве представления заголовка UITableView. Затем добавьте текущее представление в представление заголовка.
  2. полный - (void)scrollViewDidScroll:(UIScrollView *)scrollView; . ТН функцию для проверки contentoffset просмотра прокрутки, и установить рамки настоящего обзора.

Comments

    Ничего не найдено.