UIScrollView настраивает contentOffset при изменении contentSize
Я настраиваю состояние контроллера подробного представления, как раз перед тем, как его нажимают на navigationController
:
[self.detailViewController detailsForObject:someObject];
[self.navigationController pushViewController:self.detailViewController
animated:YES];
В DetailViewController
находится scrollView. Какое содержимое я изменяю на основе переданного объекта:
- (void)detailsForObject:(id)someObject {
// set some textView content here
self.contentView.frame = <rect with new calculated size>;
self.scrollView.contentSize = self.contentView.frame.size;
self.scrollView.contentOffset = CGPointZero;
}
Теперь все это работает, но scrollView настраивает его contentOffset
во время анимации слайдов navigationController. Значение contentOffset
будет установлено на разницу между последней версией contentSize и новой рассчитанной. Это означает, что во второй раз, когда вы откроете detailView, детали будут прокручиваться до некоторого нежелательного местоположения. Даже если я устанавливаю contentOffset
в CGPointZero
явно.
Я обнаружил, что сброс contentOffset
в - viewWillAppear
не влияет. Лучшее, что я мог придумать, - это сбросить содержимоеOffset в viewDidAppear
, что приведет к заметному перемещению содержимого вверх и вниз:
- (void)viewDidAppear:(BOOL)animated {
self.scrollView.contentOffset = CGPointZero;
}
Есть ли способ предотвратить настройку UIScrollView
его contentOffset
при изменении contentSize
?
Ответы
Ответ 1
Происходит при нажатии UIViewController
, содержащего UIScrollView
, с помощью UINavigationController
.
iOS 7
Решение 1 (код)
Установите @property(nonatomic, assign) BOOL automaticallyAdjustsScrollViewInsets
в NO
.
Решение 2 (раскадровка)
Снимите флажок Adjust Scroll View Insets
![Adjust Scroll View Insets]()
iOS 6
Решение (код)
Задайте свойство UIScrollView
contentOffset
и contentInset
в viewWillLayoutSubviews
. Пример кода:
- (void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
self.scrollView.contentOffset = CGPointZero;
self.scrollView.contentInset = UIEdgeInsetsZero;
}
Ответ 2
Причина этой проблемы остается неясной, хотя я нашел решение. Сбрасывая размер и смещение содержимого перед их настройкой, UIScrollView не будет анимировать:
- (void)detailsForObject:(id)someObject {
// These 2 lines solve the issue:
self.scrollView.contentSize = CGSizeZero;
self.scrollView.contentOffset = CGPointZero;
// set some textView content here
self.contentView.frame = <rect with new calculated size>;
self.scrollView.contentSize = self.contentView.frame.size;
self.scrollView.contentOffset = CGPointZero;
}
Ответ 3
У меня была такая же проблема с UIScrollview, где проблема была вызвана не установкой contentSize. После установки contentSize в число элементов эта проблема была решена.
self.headerScrollView.mainScrollview.contentSize = CGSizeMake(320 * self.sortedMaterial.count, 0);
Ответ 4
Является ли ваш scrollView корневым представлением элемента DetailViewController? Если да, попробуйте обернуть scrollView в простой UIView
и сделать последнее корневым представлением DetailViewController. Поскольку UIView
не имеют свойства contentOffset
, они невосприимчивы к корректировкам смещения содержимого, выполненным контроллером навигации (из-за панели навигации и т.д.).
Ответ 5
У меня возникла проблема, и для конкретного случая - я не настраиваю размер - я использовал следующее:
float position = 100.0;//for example
SmallScroll.center = CGPointMake(position + SmallScroll.frame.size.width / 2.0, SmallScroll.center.y);
То же самое будет работать с y: anotherPosition + SmallScroll.frame.size.height / 2.0
Итак, если вам не нужно изменять размер, это быстрое и безболезненное решение.