Подтвердить что ты не робот

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?

4b9b3361

Ответ 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

Итак, если вам не нужно изменять размер, это быстрое и безболезненное решение.