Саморазмерный CollectionView внутри саморазмерного TableViewCell - PullRequest
0 голосов
/ 21 июня 2020

Я потратил недели, пытаясь заставить это работать, и просмотрел множество различных предложений здесь, на форумах разработчиков Apple, Google и c. и все еще выдергиваю волосы. Любая помощь будет принята с благодарностью.

У меня есть ViewController, который содержит TableView. Это не полноэкранный tableView.

TableView построен с customTableViewCells, каждый из которых содержит CollectionView. Проблема, с которой я столкнулся, заключается в том, что строки collectionView с автоматическим изменением размера и строки tableView с самоизмерением просто не работают. Я нашел несколько вариантов в Интернете, но они, похоже, работают только частично.

Вот что я получаю при первоначальном запуске:

enter image description here

I'm including a link to the project file as that's probably easier than copying code into here: https://www.dropbox.com/sh/7a2dquvxg62aylt/AACK_TjDxT9eOShZaKi7vLYga?dl=0

Некоторые онлайн-обходные пути не работают во всех случаях - например, если вы нажмете одну из кнопок внутри CollectionView, она будет удалена, и collectionView (а затем TableView) должен измениться, но снова я не могу заставить это работать постоянно.

Некоторые из решений, которые я пробовал:

Саморазмерные ячейки UICollectionView с автоматической компоновкой

UICollectionView внутри UITableViewCell - динамика c высота?

Dynami c высота для UITableView на основе динамического c представления коллекции

UITableViewCell с автоматическим изменением размера, который содержит UICollectionView

Любая помощь будет принята с благодарностью.

1 Ответ

1 голос
/ 22 июня 2020

Я понял, в чем дело. Есть несколько вещей, которые необходимо исправить:

  1. Вам нужно установить приблизительную высоту строки (с фактическим значением) и установить высоту строки как автоматически c. Вы сделали наоборот. Поэтому, пожалуйста, замените функцию setupTableView на приведенную ниже. Кроме того, вам нужно установить делегата, чего вы не делали. Поэтому убедитесь, что вы добавили UITableViewDelegate рядом с именем вашего класса и назначили его внутри setupTableView (), как я сделал ниже.

    func setupTableView() {
        view.addSubview(tempTableView)
        NSLayoutConstraint.activate([
            tempTableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            tempTableView.topAnchor.constraint(equalTo: view.topAnchor, constant: 200),
            tempTableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            tempTableView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -200)
        ])
        tempTableView.rowHeight = UITableView.automaticDimension
        tempTableView.estimatedRowHeight = 90
        tempTableView.register(CustomTableViewCell.self, forCellReuseIdentifier: CustomTableViewCell.cellIdentifier)
        tempTableView.dataSource = self
        tempTableView.delegate = self
        tempTableView.translatesAutoresizingMaskIntoConstraints = false
        tempTableView.layoutIfNeeded()
    }
    
  2. Внутри cellForRowAt добавьте layoutIfNeeded, чтобы убедиться, что ячейки имеют автоматический размер правильно:

    extension ViewController: UITableViewDataSource, UITableViewDelegate {
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            2
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tempTableView.dequeueReusableCell(withIdentifier: CustomTableViewCell.cellIdentifier) as! CustomTableViewCell
            cell.layoutIfNeeded()
            return cell
        }
    }
    
  3. Ваш CustomCollectionView должен быть подклассом UICollectionViewDelegateFlowLayout.

  4. Убедитесь, что вы назначили переменную сконфигурированнойCollectionViewLayout для вашего collectionView:

    func setupCollectionView() {
        backgroundColor = .systemPink
        isScrollEnabled = false
        register(CustomCollectionViewCell.self, forCellWithReuseIdentifier: CustomCollectionViewCell.cellIdentifier)
        dataSource = self
        self.collectionViewLayout = configuredCollectionViewFlowLayout
    }
    
  5. Наконец, добавьте эти 3 переопределения, чтобы сделать ваш collectionView автоматический размер в зависимости от его содержимого (внутри CustomCollectionView):

    override var intrinsicContentSize: CGSize {
         self.layoutIfNeeded()
         return self.contentSize
     }
    
     override var contentSize: CGSize {
         didSet{
             self.invalidateIntrinsicContentSize()
         }
     }
    
     override func reloadData() {
         super.reloadData()
         self.invalidateIntrinsicContentSize()
     }
    

Вот как вы запускаете перерисовку ячейки при нажатии кнопки. Я не использую протокол, но, пожалуйста, сделайте это просто, чтобы показать вам идею:

func tokenTapped(withTitle title: String) {
    guard let indexOfItemToRemove = tokens.sampleData.firstIndex(where: {$0.name == title}) else { return }
    tokens.sampleData.remove(at: indexOfItemToRemove)
    DispatchQueue.main.async {
        self.performBatchUpdates({
            self.deleteItems(at: [IndexPath(item: indexOfItemToRemove, section: 0)])
        }) { (true) in
            if let tableView = self.superview?.superview?.superview as? UITableView {
                print("tableview updates")
                tableView.beginUpdates()
                tableView.endUpdates()
                DispatchQueue.main.async {
                    tableView.layoutIfNeeded()
                }
            }
        }
    }
}
...