Вызов invalidateLayout() или reloadData() для перезагрузки UICollectionView, созданного из раскадровки после поворота устройства

Внутри UITableViewController, UITableViewCell у меня есть сетка с фиксированным количеством статических UICollectionViewCells (без интервала) в строке.

extension NounsTVC: UICollectionViewDataSource {

    func collectionView( _ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return cellIds.count
    }

    func collectionView( _ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell( withReuseIdentifier: cellIds[indexPath.item], for: indexPath)
        cell.layer.borderColor = UIColor.gray.cgColor
        cell.layer.borderWidth = 0.5
        return cell
    }
}

extension NounsTVC: UICollectionViewDelegateFlowLayout
{
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 0
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return 0
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let availableWidth = collectionView.bounds.size.width
        let minimumWidth = floor(availableWidth / cellsPerRow)
        let remainder = availableWidth - minimumWidth * CGFloat(cellsPerRow)

        let columnIndex = indexPath.row % Int(cellsPerRow)
        let cellWidth = CGFloat(columnIndex) < remainder ? minimumWidth + 1 : minimumWidth
        return CGSize(width: cellWidth, height: 45)
    }
}

Работает отлично.

Но, когда я поворачиваю устройство, ему нужно вспомнить эти методы компоновки.

Похоже на ответ: Swift: как обновить макет UICollectionView после поворота устройства

Но у меня нет моего UICollectionView как invalidLayout(), потому что UICollectionView создан в IB (как я понимаю), так как мне вызвать invalidateLayout на моем UICollectionView?

Почему вы не недействительныLayout () для CollectionView? при изменении ориентации устройства

Nikunj Kumbhani 19.04.2019 12:36

У вас есть доступ к UICollectionView из UITableViewCell? Если да, переопределите layoutSubviews в UITableViewCell и вызовите invalidateLayout в UICollectionView там.

surToTheW 19.04.2019 13:48

@surToTheW - с ячейками, созданными статически в раскадровке, я не уверен, как создать экземпляр UITableViewCell или получить к нему доступ? @ Nikunj - можете ли вы дать ссылку на полную информацию? попытаюсь.

DrWhat 19.04.2019 15:52

Я пропустил часть о статических ячейках. Вы можете предоставить им выходы в TableViewController. Или лучше магазинную коллекцию. Сколько в них клеток? Затем вы можете переопределить viewWillTransitionToSize:withTransitionCoordinator: или viewWillLayoutSubviews и вызвать для них invalidateLayout.

surToTheW 19.04.2019 16:48

@surToTheW - да, это точно идеально. Спасибо. У меня были проблемы с подключением в IB (он не будет делать это с помощью перетаскивания ctrl), но с вашим разъяснением я закодировал его и подключил в обратном порядке, и теперь это работает. Еще раз спасибо.

DrWhat 21.04.2019 10:38

Если выходы представления коллекции НЕ находятся в контроллере табличного представления, а находятся в пользовательской UITableViewCell, как мне вызвать неверный макет при вращении устройства?

DrWhat 29.04.2019 15:53

Если выходы представления коллекции находятся НЕ в контроллере табличного представления, а в пользовательской UITableViewCell, то .invalidateLayout можно вызвать в функции traitCollectionDidChange.

DrWhat 29.04.2019 16:26
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
1 445
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В описанной выше ситуации были выявлены две проблемы.

Во-первых, xcode не создавал IBOutlet в моем пользовательском UITableViewCell, перетаскивая линию между раскадровкой и файлом .swift (очевидно, ошибка в некоторых созвездиях). Решение заключалось в том, чтобы ввести код вручную и перетащить его, удерживая нажатой клавишу CTRL, в обратном порядке к правильному представлению в раскадровке.

@IBOutlet weak var myCollectionView: UICollectionView!

Во-вторых, поскольку представление коллекции было создано в пользовательской UITableViewCell, было невозможно использовать viewWillTransitionToSize:withTransitionCoordinator: или viewWillLayoutSubviews (методы табличного представления). Однако в UITableViewCell есть следующее, где можно вызвать .invalidateLayout():

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?)
{
    super.traitCollectionDidChange(previousTraitCollection)
    guard previousTraitCollection != nil else
    { return }
    myCollectionView.collectionViewLayout.invalidateLayout()
}

Другие вопросы по теме