Non-Scrolling UICollectionView внутри UITableViewCell Динамическая высота - PullRequest
1 голос
/ 08 марта 2019

Я добавил UICollectionView внутри UITableViewCell, для этого я создал XIB файл. Проверьте следующее изображение:

UITableView Xib

Вы можете видеть на изображении выше всю иерархию вида и ограничения.

Примечание: У меня отключен вид коллекции по вертикали и горизонтали прокрутка, потому что я хочу динамически увеличить UITableViewCell высоту. Итак, я взял выход ограничения высоты представления коллекции и изменил его программно на основе элемента, доступного в представлении коллекции.

Размер элемента представления коллекции, если фиксированный, ширина пропорциональна виду коллекции, а высота 30

Я зарегистрировал этот xib в своем табличном представлении, используя следующий код.

self.tblSubCategory.register(SubCategoryTVC.Nib(), forCellReuseIdentifier: "SubCategoryTVC")

Вот мой код SubCategoryTVC:

class SubCategoryTVC: UITableViewCell {

    @IBOutlet weak var categoryView                 : UIView!
    @IBOutlet weak var categoryImageView            : UIView!
    @IBOutlet weak var imgCategory                  : UIImageView!
    @IBOutlet weak var lblCategoryName              : UILabel!

    @IBOutlet weak var cvSubcategory                : UICollectionView!

    // MARK: Constrains's Outlet
    @IBOutlet weak var const_cvSubcategory_height   : NSLayoutConstraint!


    class func Nib() -> UINib {
        return UINib(nibName: "SubCategoryTVC", bundle: nil)
    }

    func setCollectionView(dataSourceDelegate: UICollectionViewDataSource & UICollectionViewDelegate, forRow row: Int) {
        self.cvSubcategory.delegate = dataSourceDelegate
        self.cvSubcategory.dataSource = dataSourceDelegate
        self.cvSubcategory.tag = row
        self.cvSubcategory.reloadData()
    }

    override func awakeFromNib() {
        super.awakeFromNib()
    }
}

UITableViewDataSource:

extension SignupSecondStepVC: UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 5
    }

    //------------------------------------------------------------------------------

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "SubCategoryTVC", for: indexPath) as! SubCategoryTVC

        cell.lblCategoryName.text = "Category \(indexPath.row)"

        cell.cvSubcategory.register(SubCategoryCVC.Nib(), forCellWithReuseIdentifier: "SubCategoryCVC")

        return cell
    }
}

UITableViewDelegate:

extension SignupSecondStepVC: UITableViewDelegate {

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {

        guard let subCategoryCell = cell as? SubCategoryTVC else { return }

        // This line of code set dataSource and delegate to `SignupSecondStepVC` instead of `SubCategoryTVC`
        subCategoryCell.setCollectionView(dataSourceDelegate: self, forRow: indexPath.row)

        subCategoryCell.cvSubcategory.setNeedsLayout()

        // This will change height of collection view based on item available.
        subCategoryCell.const_cvSubcategory_height.constant = 30 * 5

        subCategoryCell.cvSubcategory.setNeedsLayout()
        subCategoryCell.contentView.layoutIfNeeded()
    }

    //------------------------------------------------------------------------------

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }

    //------------------------------------------------------------------------------

    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }
}

Над кодом UITableView, см. Следующий код UICollectionView

UICollectionViewDataSource:

extension SignupSecondStepVC: UICollectionViewDataSource {

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

    //------------------------------------------------------------------------------

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SubCategoryCVC", for: indexPath) as! SubCategoryCVC

        cell.btnSelection.setCornerRadius(radius: cell.btnSelection.frame.size.height / 2)
        cell.lblSubCategoryName.text = "SubCategory \(indexPath.row)"

        return cell
    }
}

UICollectionViewDelegateFlowLayout:

extension SignupSecondStepVC: UICollectionViewDelegateFlowLayout {

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        let width = collectionView.frame.size.width
        return CGSize(width: width, height: 30)
    }
}

После всего этого у меня возникли проблемы с загрузкой ячеек и пользовательским интерфейсом. Когда я запускаю приложение и загружаю данные в первый раз, возникает проблема пользовательского интерфейса, а не правильная загрузка данных. Смотрите следующее видео, чтобы вы могли понять мою актуальную проблему.

Выпуск видео

Пожалуйста, помогите мне решить эту проблему.

1 Ответ

4 голосов
/ 08 марта 2019

Вам необходимо связать свой делегат / источник данных collectionView с TableViewCell и использовать ниже func в tableViewcell. Обязательно отключите прокрутку CollectionView.

override func systemLayoutSizeFitting(_ targetSize: CGSize, withHorizontalFittingPriority horizontalFittingPriority: UILayoutPriority, verticalFittingPriority: UILayoutPriority) -> CGSize {

    self.layoutIfNeeded()
    let contentSize = self.cvSubcategory.collectionViewLayout.collectionViewContentSize
    if self.cvSubcategory.numberOfItems(inSection: 0) < 4 {
        return CGSize(width: contentSize.width, height: 120) // Static height if colview is not fitted properly.
    }

    return CGSize(width: contentSize.width, height: contentSize.height + 20) // 20 is the margin of the collectinview with top and bottom
}

Пример решения вашего проекта: https://github.com/thedahiyaboy/DynamicCollectionApp


Для будущих целей вы можете взять ссылку из этого поста: Dynamic CollectionViewCell в TableViewCell Swift

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...