UICollectionView внутри UITableViewCell

swift

#1

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

господа, готов заплатить за эту задачу так как уже всю голову поломал, первая проблема:

  1. настройка автовысоты у таблицы содержащей коллекцию.

  2. при скроле одной колекции смещать все видимые и невидимые колекции.


#2

2й пункт подразумевает что все коллекции будут иметь одинаковое кол-во ячеек с одинаковой шириной?


#3

да все коллекции имеют одинаковое количество ячеек и одинаковую ширину, НО возможно разную высоту, те в рамках одной коллекции высота и ширина будет одинакова у всех ячеек, а между колекциями будет отличаться.

внутри коллекций будет лайбл, в том числе и у хедера колекции с отступами 15 15 15 15, который и будет колекцию тянуть, он будет высчитываться максимальным и присваиваться всем ячейкам коллекции


#4

Быстрый план из головы

  1. заведите переменную, которая будет следить за смещением вашей коллекции, изначально будет 0
  2. в методе tableView(cellForRowAt) передавайте в ячейку эту переменную со смещением
  3. в ячейке с коллекцией, после инициализации всех элементов и прорисовки, делайте скрол коллекции на полученную величину
  4. при скроле коллекции, отлавливайте ее положение по Х и передавайте обратно в класс с таблицей, посредством делегата
  5. в методе делегата (в классе с таблицей), получая новое смещение по Х, получите все видимые ячейки, за исключением той, в которой вы делаете скрол коллекции
  6. в классе ячейки таблицы с коллекцией, создайте метод, который будет получать новое смещение и делать скрол коллекции
  7. из метода делегата (в классе с таблицей) после того как получили нужные видимые ячейки, вызовите у всех метод для обновления скрола и передайте в него переменную со смещением

логика работы примерная, возможно сразу и не будет работать. но так бы делал я изначально. после чего уже можно было бы что-то оптимизировать.


#5

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


#6

#7

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

import UIKit

class PropertyComparisonTableViewCell: UITableViewCell, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

@IBOutlet weak var values: UICollectionView!
let width: CGFloat = 100
var maxHeight: CGFloat = 0
let indents: CGFloat = 30
var rowIndex: Int!
var propertyComparison: PropertyComparison! {
    
    didSet {
        
        values.dataSource = self
        // define height of cells
        defineHeightWith(text: propertyComparison.name)
        for value in propertyComparison.values {
            
            defineHeightWith(text: value)
        }
        values.heightAnchor.constraint(equalToConstant: maxHeight + indents).isActive = true
        let cellSize = CGSize(width: width + indents, height: maxHeight + indents)
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        layout.itemSize = cellSize
        layout.minimumLineSpacing = 4
        layout.headerReferenceSize = cellSize
        layout.sectionHeadersPinToVisibleBounds = true
        layout.sectionInset = UIEdgeInsets(top: 0, left: 4, bottom: 0, right: 0)
        values.setCollectionViewLayout(layout, animated: false)
        values.reloadData()
    }
}

private func defineHeightWith(text: String) {
    
    let fontStyle: UIFont = UIFont(name: "PTSans-Regular", size: 13) ?? UIFont.systemFont(ofSize: 13)
    let height = text.heightWithConstrainedWidth(width: width, font: fontStyle)
    if height > maxHeight {

        maxHeight = height
    }
}

func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {

    if let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "header", for: indexPath) as? PropertyHeaderComparisonCollectionReusableView {
        
        header.index = rowIndex
        header.label.text = propertyComparison.name
        return header
    }
    return UICollectionReusableView(frame: .zero)
}

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

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    
    if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "value", for: indexPath) as? ValueComparisonCollectionViewCell {
        
        cell.index = rowIndex
        cell.label.text = propertyComparison.values[indexPath.row]
        return cell
    }
    return UICollectionViewCell(frame: .zero)
}

}


#8

или в классе где сама таблица?

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    
    if let propertyComparison = propertyComparison {
        
        return propertyComparison.count //+ 1
    }
    return 0
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
    if let cell = tableView.dequeueReusableCell(withIdentifier: "property", for: indexPath) as? PropertyComparisonTableViewCell, let propertyComparison = propertyComparison {
        
        //collectionsView.append(cell.values)
        //cell.values.delegate = self
        cell.rowIndex = indexPath.row
        cell.propertyComparison = propertyComparison[indexPath.row]
        return cell
    } //else if let cell = tableView.dequeueReusableCell(withIdentifier: "buttons", for: indexPath) as? ButtonsComparisonTableViewCell, let propertyComparison = propertyComparison, let products = products, indexPath.row == propertyComparison.count {

// collectionsView.append(cell.buttons)
// cell.buttons.delegate = self
// cell.products = products
// cell.productComparisonVC = self
// //sizeCache[indexPath] = 59
// return cell
// }
return UITableViewCell(frame: .zero)
}

override func viewDidLoad() {
    
    super.viewDidLoad()
    fetchProductsWith()
    properties.tableFooterView = UIView()
    properties.separatorStyle = .none
    
    properties.estimatedRowHeight = 44
    properties.rowHeight = UITableView.automaticDimension
}

#9

Возможно поможет Texture


#10

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