Я пытался подражать этому поведению в ситуации, когда мне требовался настраиваемый заголовок, расположенный около UITableView. Я свернул свою собственную «навигационную» панель, потому что она находится под множеством других вещей на странице, и я хотел, чтобы заголовки разделов соответствовали поведению «стыковки» по умолчанию. Я думаю, что нашел довольно умный и лаконичный способ настроить UITableView / UIScrollView вместе с другим объектом в стиле, аналогичном тому, который мы видели в Facebook / Instagram / Chrome / и т. Д. Программы.
В моем файле .xib мои компоненты загружены в произвольном виде: http://imgur.com/0z9yebJ (извините, у меня нет репутации для встроенных изображений)
Обратите внимание, что на левой боковой панели таблица расположена за основным видом заголовка. Вы не можете сказать по снимку экрана, но он также имеет ту же позицию по оси Y, что и основной вид заголовка. Поскольку он простирается вне поля зрения, свойство contentInset в UITableView установлено на 76 (высота основного представления заголовка).
Чтобы заставить представление основного заголовка скользить вверх вместе с UIScrollView, я использую методы scrollViewDidScroll UIScrollViewDelegate для выполнения некоторых вычислений и изменения contentInset UIScrollView, а также фрейма основного представления заголовка.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
UIEdgeInsets insets = scrollView.contentInset;
//tableViewInsetDelta and tableViewOriginalInsetValue are NSInteger variables that I set to 0 and 76, respectively, in viewDidLoad
tableViewInsetDelta = tableViewOriginalInsetValue + scrollView.contentOffset.y;
insets.top = tableViewOriginalInsetValue - tableViewInsetDelta;
if (scrollView.contentOffset.y > -76 && scrollView.contentOffset.y < 0) {
[scrollView setContentInset:insets];
self.pathTitleContainer.frame = CGRectMake(self.pathTitleContainer.frame.origin.x, 44 - tableViewInsetDelta, self.pathTitleContainer.frame.size.width, self.pathTitleContainer.frame.size.height);
} else if (scrollView.contentOffset.y > 0) {
insets.top = 0;
[scrollView setContentInset:insets];
self.pathTitleContainer.frame = CGRectMake(self.pathTitleContainer.frame.origin.x, -32, self.pathTitleContainer.frame.size.width, self.pathTitleContainer.frame.size.height);
} else if (scrollView.contentOffset.y < -76) {
insets.top = 76;
[scrollView setContentInset:insets];
self.pathTitleContainer.frame = CGRectMake(self.pathTitleContainer.frame.origin.x, 44, self.pathTitleContainer.frame.size.width, self.pathTitleContainer.frame.size.height);
}
}
Первый оператор if выполняет большую часть тяжелой работы, но мне пришлось включить два других для обработки ситуаций, когда пользователь принудительно перетаскивает, а начальные значения contentOffset, отправленные в scrollViewDidScroll, выходят за пределы диапазона первого оператора if .
В конечном счете, у меня это действительно хорошо работает. Я ненавижу загружать свои проекты кучей раздутых подклассов. Я не могу сказать, является ли это лучшим решением с точки зрения производительности (я всегда не решался помещать какой-либо код в scrollViewDidScroll, поскольку он вызывается все время), но размер кода - самый маленький, который я видел в любом решение этой проблемы, и оно не связано с вложением UITableView в UIScrollView (Apple не советует этого в документации, а события касания в UITableView выглядят немного странно). Надеюсь, это кому-то поможет!