Похоже, что вы всегда просматриваете представление таблицы вверху, когда вы показываете раскрывающееся представление. Предполагая, что это так, есть лучший способ сделать это.
UITableView
наследует contentInset
Недвижимость от UIScrollView
. Свойство contentInset
определяет границу на каждом краю прокрутки. Каждая граница имеет свою толщину, которая по умолчанию равна нулю. Эти границы просто влияют на то, насколько далеко прокрутка позволяет пользователю прокручивать контент - они не скрывают контент! Если вы установите верхнюю вставку больше нуля и дадите прокрутку просмотреть подпункт с отрицательным началом Y, этот субвью может быть виден на границе и будет прокручиваться вместе с остальным содержимым вида прокрутки.
Таким образом, мы установим верхнюю вставку в виде таблицы на высоту раскрывающегося окна и добавим всплывающее представление в виде подсмотра представления таблицы с его началом, установленным на отрицательное значение его высоты. Это сделает его идеально подходящим на экране над первой строкой табличного представления, и оно будет прокручиваться в виде таблицы. Когда мы обнаруживаем, что всплывающее окно полностью прокручивается, мы можем просто удалить его из представления таблицы и установить верхнюю вставку таблицы вверх к нулю.
Нам понадобится переменная экземпляра, который отслеживает текущее состояние ниспадающем ввиду:
typedef enum {
DropInViewStateHidden,
DropInViewStateAppearing,
DropInViewStateVisible
} DropInViewState;
@implementation ViewController {
DropInViewState _dropInViewState;
}
В моем тестовом проекте я использовал только кнопку, чтобы вызвать раскрывающийся в поле зрения. Вот действие:
- (IBAction)dropIn {
if (_dropInViewState != DropInViewStateHidden)
return;
CGRect frame = self.dropInView.frame;
frame.origin.y = -frame.size.height;
self.dropInView.frame = frame;
[self.tableView addSubview:self.dropInView];
self.tableView.contentInset = UIEdgeInsetsMake(frame.size.height, 0, 0, 0);
[self.tableView setContentOffset:frame.origin animated:YES];
_dropInViewState = DropInViewStateAppearing;
}
Когда свиток таблицы просматривается, мы проверяем состояние раскрывающегося списка. Если он находится в «видимом» состоянии и прокручивается за кадром, мы его скрываем. Есть сложный бит, потому что, когда мы делаем видимым вид сверху, и прокручиваем его на экран, мы можем получать сообщения scrollViewDidScroll:
, которые заставили бы нас думать, что скрытое представление скрыто. Вот почему мы начинаем в состоянии DropInViewStateAppearing
и переходим в состояние DropInViewVisible
, когда мы знаем, что представление появилось.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
switch (_dropInViewState) {
case DropInViewStateHidden:
break;
case DropInViewStateVisible:
if (scrollView.contentOffset.y >= 0) {
// dropInView has been scrolled off-screen
self.tableView.contentInset = UIEdgeInsetsZero;
[self.dropInView removeFromSuperview];
_dropInViewState = DropInViewStateHidden;
break;
}
case DropInViewStateAppearing:
// When I first add dropInView to tableView and tell tableView
// to scroll to reveal dropInView, I may get a bunch of
// scrollViewDidScroll: messages with contentOffset.y >= 0.
// I don't want those messages to hide dropInView, so I sit in
// DropInViewStateAppearing until contentOffset.y goes negative,
// which means at least part of dropInView is actually on-screen.
if (scrollView.contentOffset.y < 0)
_dropInViewState = DropInViewStateVisible;
break;
}
}
У меня есть панель поиска и тянуть к-обновлению вещи также претендующую на эту верхнюю области вставки, так что я все еще на чертежной доске, но спасибо за хороший, тщательный ответ. – danh