Swift UITableViewCell 动态布局中的 UICollectionView 无法更改单元格高度

Swift UICollectionView in a UITableViewCell dynamic layout can't change cell height

在 Xcode 8.2.1 和 Swift 3 中,我在 UITableViewCell 中有一个 UICollectionView,但我无法正确布局。基本上我希望能够看到所有的明星。我可以调整星星的大小,但我想解决根本问题,扩大蓝色带。

这是视图的截图红色带是contentView,蓝色带是collectionView。乍一看,collectionView 高度似乎是问题所在,但它实际上被其他东西隐藏了。我无法找到或更改隐藏 collectionView 单元格的任何内容。

除了导航器中嵌入的视图控制器之外,我没有使用故事板。

这是所有相关代码。

class WishListsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

var tableView: UITableView = UITableView()        
let tableCellId = "WishListsCell"
let collectionCellId = "WishListsCollectionViewCell"

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.delegate = self        
    tableView.dataSource = self 
    tableView.backgroundColor = .white
    tableView.register(WishListsCell.self, forCellReuseIdentifier: tableCellId)
    self.view.addSubview(tableView)
    tableView.translatesAutoresizingMaskIntoConstraints = false

    tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
    tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    }

        func numberOfSections(in tableView: UITableView) -> Int {        
            return wishLists.count
        }

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

        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{        
            let cell = tableView.dequeueReusableCell(withIdentifier: tableCellId, for: indexPath) as! WishListsCell      
            return cell
        }

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

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

    guard let tableViewCell = cell as? WishListsCell else { return }
    //here setting the uitableview cell contains collectionview delgate conform to viewcontroller
      tableViewCell.setCollectionViewDataSourceDelegate(dataSourceDelegate: self, forSection: indexPath.section)
    tableViewCell.collectionViewOffset = storedOffsets[indexPath.row] ?? 0
}

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

    guard let tableViewCell = cell as? WishListsCell else { return }
    storedOffsets[indexPath.row] = tableViewCell.collectionViewOffset
}
}

extension WishListsViewController: UICollectionViewDelegate , UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: collectionCellId, for: indexPath) as! WishListsCollectionViewCell
    return cell
    }

func collectionView(_ collectionView: UICollectionView,
                    layout collectionViewLayout: UICollectionViewLayout,
                    sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: 100, height: 100)
}

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

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

}

class WishListsCell: UITableViewCell {

private var collectionView: UICollectionView!
let cellId = "WishListsCollectionViewCell"


    var collectionViewOffset: CGFloat {
        get { return collectionView.contentOffset.x }
        set { collectionView.contentOffset.x = newValue }
    }


    func setCollectionViewDataSourceDelegate<D: protocol<UICollectionViewDataSource, UICollectionViewDelegate>>
        (dataSourceDelegate: D, forSection section : Int) {

        collectionView.delegate = dataSourceDelegate
        collectionView.dataSource = dataSourceDelegate
        collectionView.tag = section
        collectionView.reloadData()
    }

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
        collectionView = UICollectionView(frame: contentView.frame, collectionViewLayout: layout)
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.backgroundColor = .blue
        collectionView.register(WishListsCollectionViewCell.self, forCellWithReuseIdentifier: cellId)
        contentView.backgroundColor = .red
        self.contentView.addSubview(collectionView)        
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

class WishListsCollectionViewCell: UICollectionViewCell {

    var imageView: UIImageView

    override init(frame: CGRect) {
        imageView = UIImageView()
        super.init(frame: frame)
        contentView.addSubview(imageView)        
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.contentMode = .scaleAspectFit
        contentView.translatesAutoresizingMaskIntoConstraints = false
        imageView.backgroundColor = .white

        NSLayoutConstraint.activate([

            NSLayoutConstraint(item: imageView, attribute: .width, relatedBy: .equal,
                               toItem: contentView, attribute: .width,
                               multiplier: 1.0, constant: 0.0),

            NSLayoutConstraint(item: imageView, attribute: .height, relatedBy: .equal,
                               toItem: contentView, attribute: .height,
                               multiplier: 1.0, constant: 0.0),

            ])
    }    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

您可以使用 View Debugging

运行 项目,返回 Xcode 并单击调试栏中的调试视图层次结构按钮。或者,转到 Debug\View Debugging\Capture 查看层次结构。

现在您可以 select 红色视图,Xcode 将指示哪个视图是 selected。

了解更多信息。查看:View Debugging in Xcode

具体来说,问题是集合视图框架没有正确设置。这只是由我在接受的答案中不知道的重要提示揭示的。

已修复:

self.collectionView.frame = CGRect(0, 0, screenWidth, (screenWidth / 4) * Constants.IMAGE_ASPECT_RATIO)