Странное поведение uitableview в iOS11. Ячейки прокручиваются с анимацией push-навигации

Недавно я перенес какой-то код в новый iOS 11 beta 5 SDK.

Теперь я получаю очень запутанное поведение от UITableView. Сама таблица не такова. У меня есть пользовательские ячейки, но в большинстве случаев это просто для их роста.

Когда я нажимаю свой контроллер представления с помощью таблицы, я получаю дополнительную анимацию, где ячейки «прокручиваются вверх» (или, возможно, весь кадр таблицы), и вниз по анимации push / pop навигации. См. Gif:

волнистый стол

Я вручную создаю loadView методе loadView и loadView ограничения автоматического макета, чтобы они были равны ведущей, конечной, верхней, нижней части надзора tableview. Супервизор – это корневой вид контроллера вида.

Просмотр кода нажатия контроллера очень стандартен: self.navigationController?.pushViewController(notifVC, animated: true)

Тот же код обеспечивает нормальное поведение на iOS 10.

Не могли бы вы указать мне направление того, что не так?

EDIT: Я создал очень простой контроллер таблицы, и я могу воспроизвести там такое же поведение. Код:

 class VerySimpleTableViewController : UITableViewController { override func viewDidLoad() { super.viewDidLoad() self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell") } override func numberOfSections(in tableView: UITableView) -> Int { return 1 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 4 } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) cell.textLabel?.text = String(indexPath.row) cell.accessoryType = .disclosureIndicator return cell } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableView.deselectRow(at: indexPath, animated: true) let vc = VerySimpleTableViewController.init(style: .grouped) self.navigationController?.pushViewController(vc, animated: true) } } 

EDIT 2: я смог сузить вопрос до моей настройки UINavigationBar. У меня есть такая настройка:

rootNavController.navigationBar.setBackgroundImage(createFilledImage(withColor: .white, size: 1), for: .default)

где createFilledImage создает квадратное изображение с заданным размером и цветом.

Если я прокомментирую эту строку, я вернусь к нормальному поведению.

Буду признателен за любые мысли по этому вопросу.

Это связано с тем, что UIScrollView's (UITableView является подклассом UIScrollview) новым свойством contentInsetAdjustmentBehavior , которое по умолчанию установлено на .automatic .

Вы можете переопределить это поведение со следующим фрагментом в viewDidLoad любых затронутых контроллеров:

  tableView.contentInsetAdjustmentBehavior = .never 

https://developer.apple.com/documentation/uikit/uiscrollview/2902261-contentinsetadjustmentbehavior

В дополнение к ответу Магги

Objective-C

 if (@available(iOS 11.0, *)) { scrollViewForView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; } 

Вы можете редактировать это поведение сразу по всему приложению, используя NSProxy, например, doneFinishLaunchingWithOptions:

 if (@available(iOS 11.0, *)) { [UIScrollView appearance].contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; } 

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

 if #available(iOS 11, *) { tableView.contentInset = self.collectionView.safeAreaInsets } 

Это больше похоже на ошибку, чем предполагаемое поведение. Это происходит, когда панель навигации не является полупрозрачной или если установлено фоновое изображение.

Если вы просто установили contentInsetAdjustmentBehavior на .never, вставки содержимого не будут правильно установлены на iPhone X, например, содержимое будет входить в нижнюю область под полосами прокрутки.

Необходимо сделать две вещи:
1. предотвращать анимацию scrollView на push / pop
2. Сохраняйте .автоматическое поведение, потому что оно необходимо для iPhone X. Без этого, например, в портрете, контент будет идти ниже нижней полосы прокрутки.

Примечание. Если вы используете UIScrollView в ландшафтном режиме, он по-прежнему не устанавливает горизонтальные вставки правильно (другая ошибка?), Поэтому вы должны вывести ведущие / завершающие строки scrollView в safeAreaInsets в IB.

Примечание 2: В приведенном ниже решении также есть проблема, что если tableView прокручивается в нижнюю часть, и вы нажимаете контроллер и выскакиваете назад, он больше не будет внизу.

 override func viewDidLoad() { super.viewDidLoad() // This parts gets rid of animation when pushing if #available(iOS 11, *) { self.tableView.contentInsetAdjustmentBehavior = .never } } override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) // This parts gets rid of animation when popping if #available(iOS 11, *) { self.tableView.contentInsetAdjustmentBehavior = .never } } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) // This parts sets correct behaviour(insets are correct on iPhone X) if #available(iOS 11, *) { self.tableView.contentInsetAdjustmentBehavior = .automatic } } 

Вот как мне удалось исправить эту проблему, хотя я все же позволяю iOS 11 автоматически устанавливать вставки . Я использую UITableViewController .

  • Выберите «Расширить края под верхними барами» и «Расширьте края под непрозрачными полосками» в своем контроллере просмотра в раскадровке (или программно ). Вставка в безопасную зону предотвратит попадание вашего представления под верхнюю панель.
  • Проверьте кнопку «Вставки в безопасную зону» на вашем столе в вашем раскадровке. (или tableView.insetsContentViewsToSafeArea = true ) – Возможно, это не обязательно, но это то, что я сделал.
  • Установите для параметра настройки вставки содержимого значение «Прокручиваемые оси» (или tableView.contentInsetAdjustmentBehavior = .scrollableAxes ). tableView.contentInsetAdjustmentBehavior = .scrollableAxes могут работать, но я не тестировал.

Еще одна попытка попробовать, если все остальное не удастся:

Переопределить viewSafeAreaInsetsDidChange метод UIViewController чтобы заставить табличное представление принудительно установить вставки прокрутки в вставки безопасной области. Это связано с настройкой «Никогда» в ответе Магги.

 - (void)viewSafeAreaInsetsDidChange { [super viewSafeAreaInsetsDidChange]; self.tableView.contentInset = self.view.safeAreaInsets; } 

Примечание: self.tableView и self.view должны быть одинаковыми для UITableViewController

Удалите этот код для меня

 self.edgesForExtendedLayout = UIRectEdgeNone 

В моем случае это сработало (поместите его в viewDidLoad):

 self.navigationController.navigationBar.translucent = YES; 

убедитесь, что вместе с вышеприведенным кодом добавьте дополнительный код следующим образом. Он решил проблему

 override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) // print(thisUISBTV.adjustedContentInset) } 
  • Серая область ниже сгруппирована UITableView
  • Перекрывающаяся таблица просмотра прокрутки tableView за ней
  • cellForRowAtIndexPath возвращает ноль
  • Первая ячейка ios не начинается с вершины UITableView
  • Общий UITableView
  • Нерегулярные анимации из UITableView's deleteRowsAtIndexPaths: withRowAnimation:
  • self.tableView.delegate = self Swift
  • iOS - индекс UITableView: есть ли способ выделить выделенный алфавит?
  • UITableView indexPathsForVisibleRows возвращает неверные строки
  • пользовательский UIButton с изображением
  • Как установить выделение для одного для всех разделов в представлении таблицы в ios, цель c
  • Interesting Posts

    Почему XCode-архив отличается от XCode для сборки / запуска на iPhone

    Как создать прозрачный оверлей по всему экрану, включая активную клавиатуру

    Как проверить, не является ли NSDictionary низом в Swift 2

    Как очистить номер значка при сохранении центра уведомлений

    Добавление NSData в NSDirectory (JSON) получение недопустимого типа в ошибке JSON write (NSConcreteMutableData)

    UIButton в UIView внутри UIScrollView позволяет получать события касания, когда внешний исходный кадр

    Xcode 6 ScrollView с универсальной компоновкой

    AIR 2.7 для iOS, воспроизводящего аудио в фоновом режиме?

    Как изменить фон UINavigationBar?

    Как включить lpsolve, c-based библиотеку линейного программирования в моем приложении ios

    Почему, когда я устанавливаю значение низкой продолжительности для моего CABasicAnimation, он прыгает?

    как отменить localNotification нажатием кнопки в swift?

    Отказ от полного доступа к пользовательской клавиатуре

    iOS Game Center – Использует ли он местный высокий балл после добавления в будущую сборку?

    Создайте UIImage с сплошным цветом в Swift

    Давайте будем гением компьютера.