【问题标题】:Swift - set height for UICollectionViewCell inside UITableViewCellSwift - 为 UITableViewCell 内的 UICollectionViewCell 设置高度
【发布时间】:2017-05-15 00:54:28
【问题描述】:

我创建了包含多个部分的UITableView。每个部分都有一行(UITableViewCell),在这一行里面,我有UICollectionView,里面有UICollectionViewCell。滚动工作正常。但是,当我更改表格行高时,UICollectionView 高度保持不变。如何解决这个问题?

class ViewController: UIViewController {

    var tab: HorizontalSelector? = nil

    @IBOutlet weak var tabView: UIView!

    override func viewDidLoad() {
       super.viewDidLoad()

       tab = HorizontalSelector(frame: self.tabView.frame)

       tab?.addSection("Jedna", withHeight: 100)
       tab?.addSection("Middle", withHeight: 100)
       tab?.addSection("Dva", withHeight: 100)

        self.tabView.addSubview(tab!)
    }
}

水平选择器类

class HorizontalSelector: UITableView, UITableViewDataSource, UITableViewDelegate {

    let CELL_REUSE_ID = "cellSectionRow"
    let DEFAULT_ROW_HEIGHT: CGFloat = 44

    var sectionHeights: [CGFloat] =  []
    var sections: [String] = []

    init(frame: CGRect){

        var f: CGRect = frame
        f.origin.x = 0
        f.origin.y = 0

        super.init(frame: f, style: UITableViewStyle.plain)

        self.initialize()
    }

    override init(frame: CGRect, style: UITableViewStyle) {
        super.init(frame: frame, style: style)

        self.initialize()
    }

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

    func initialize(){
        self.register(SectionCell.self, forCellReuseIdentifier: CELL_REUSE_ID)

        self.dataSource = self
        self.delegate = self

        self.backgroundColor = UIColor.blue
    }

    func addSection(_ section: String){
        sections.append(section)
        sectionHeights.append(DEFAULT_ROW_HEIGHT)
    }

    func addSection(_ section: String, withHeight: CGFloat){
        sections.append(section)
        sectionHeights.append(withHeight)
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return sectionHeights[indexPath.section]
    }

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

    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return sections[section]
    }

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let sectionCell = tableView.dequeueReusableCell(withIdentifier: CELL_REUSE_ID) as! SectionCell

        sectionCell.backgroundColor = UIColor.brown

        return sectionCell
    }
}

单个表部分的类

class SectionCell: UITableViewCell {

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

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

        self.initialize()
    }

    override func awakeFromNib() {
        super.awakeFromNib()

        self.initialize()
    }

    func initialize(){

        let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal

        self.contentView.addSubview(SectionCellRowCollection(frame: self.contentView.bounds, collectionViewLayout: layout))
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

单个表部分中的集合类

class SectionCellRowCollection: UICollectionView, UICollectionViewDataSource, UICollectionViewDelegate {

    private let COLLECTION_CELL_ID = "collectionCell"

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

    override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout){
        super.init(frame: frame, collectionViewLayout: layout)

        self.initialize()
    }

    private func initialize(){
        self.register(SectionCellRowCollectionCell.self, forCellWithReuseIdentifier: COLLECTION_CELL_ID)
        self.dataSource = self
        self.delegate = self

        self.backgroundColor = UIColor.yellow
    }

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

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

        cell.backgroundColor = UIColor.gray

        return cell

    }
}

集合内单个单元格的类

class SectionCellRowCollectionCell: UICollectionViewCell{

    var imageView: UIImageView!

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

    override init(frame: CGRect) {
        super.init(frame: frame)

        imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height*2/3))
        imageView.contentMode = UIViewContentMode.scaleAspectFit
        imageView.image = UIImage(named: "Swift-cover")
        contentView.addSubview(imageView)

        self.backgroundColor = UIColor.green
    }
}

【问题讨论】:

    标签: ios swift uitableview uicollectionview


    【解决方案1】:

    为您的 collectionView 设置约束,它将根据这些约束更改其框架:

    class SectionCell: UITableViewCell {
        private var collectionView: SectionCellRowCollection!
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
        }
    
        override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)
            initialize()
        }
    
        override func awakeFromNib() {
            super.awakeFromNib()
            initialize()
        }
    
        private func initialize() {
            translatesAutoresizingMaskIntoConstraints = false
            let layout = UICollectionViewFlowLayout()
            layout.scrollDirection = .horizontal
            collectionView = SectionCellRowCollection(frame: contentView.bounds, collectionViewLayout: layout)
            collectionView.translatesAutoresizingMaskIntoConstraints = false
            contentView.addSubview(collectionView)
            // constraints
            collectionView.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true
            collectionView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
            collectionView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
            collectionView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
    
        }
    }
    

    【讨论】:

    • 没用...它将以“无法同时满足约束”和一堆错误输出结束
    • 编辑了我的答案。此外,在将新行添加到您的数组后,不要忘记调用 reloadData()
    • 还是同样的错误。完整的错误输出:pastebin.com/5A1DZT7e
    • 我的错,错过了一行collectionView.translatesAutoresizingMaskIntoConstraints = false 。请再试一次。
    【解决方案2】:

    您在 tableviewCell 中有 collectionView,因此故事板中有一些静态的 collectionView 高度,因此无论 tableview 的高度如何,collectionView 都将其高度作为其不剪辑到边界。所以要解决该问题,您必须给出 tableView 的高度

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
    {
        return 100.0;//Choose your custom row height
    }
    
    Then set the collectionView cell height that must be cell or equal to tableview height 
    
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
        return CGSize(width: screenWidth, height:90 );
    }
    

    【讨论】:

    • 这会设置collectionViewCell的大小,但是collectionView本身的高度还是不够。
    • 为此,您需要设置 collectionView 高度约束,然后创建该约束的出口,然后将集合高度约束设置为任何值,或者将 collectionView 约束(如前导、尾随、顶部、底部)设置为 UITableViewCell,然后它自动采用高度 collectionView 单元格的 UITableViewCell 单元格的任何高度。如果您有任何困惑,请告知。谢谢
    • 您能否为一个约束提供一个简单的示例?我现在只使用了 Interface Builder 中的约束。
    • 我在 IB 中没有约束,整个“UI”都是由上面的代码构建的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-20
    • 1970-01-01
    • 2011-06-04
    • 1970-01-01
    • 2011-08-06
    相关资源
    最近更新 更多