tableview 的行高没有变化,CollectionView 正在捕获所有未使用的空间,而不是在 tableViewCell 中调整自身大小

Posted

技术标签:

【中文标题】tableview 的行高没有变化,CollectionView 正在捕获所有未使用的空间,而不是在 tableViewCell 中调整自身大小【英文标题】:tableview's Row height is not changing , CollectionView is capturing all the unused space instead of resizing itself in the tableViewCell 【发布时间】:2016-06-13 13:19:35 【问题描述】:

我按照这个tutorial 将UICollectionView 放入UITableViewCell,在我的UICollectionViewCell 中,有一个图像视图。因此,当我运行我的应用程序时,集合视图不会同时在我的单元格中调整自身大小,我放置了一个根据内容调整自身大小的文本视图,请参见下图:

在这第一张图片中,我在顶部有一个文本视图,其中有一些文本,在它下面(粉红色背景)是我的收藏视图,在绿色背景里面是我的图像视图,如您所见该集合视图占用了额外的空间,而不是像文本视图那样减少自身。

在第二张图片中,您可以看到我的 textView 比之前有更多内容,因此它的大小调整后现在与 CollectionView 重叠

这是我的 TableViewCell:

    class TableViewCell: UITableViewCell 


    @IBOutlet var txtView: UITextView!
    @IBOutlet private weak var collectionView: UICollectionView!

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

//        collectionView.frame = self.bounds;
//        collectionView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
    

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

        // Configure the view for the selected state
    

    func setCollectionViewDataSourceDelegate
        <D: protocol<UICollectionViewDataSource, UICollectionViewDelegate>>
        (dataSourceDelegate: D, forRow row: Int) 

        collectionView.delegate = dataSourceDelegate
        collectionView.dataSource = dataSourceDelegate
        collectionView.tag = row
        collectionView.reloadData()
    


    var collectionViewOffset: CGFloat 
        get 
            return collectionView.contentOffset.x
        

        set 

            collectionView.contentOffset.x = newValue

        
    



这是我的 collectionViewCell

    class CollectionViewCell: UICollectionViewCell 

    @IBOutlet var imgView: UIImageView!


    override func awakeFromNib() 

        self.setNeedsLayout()
//        
//        self.contentView.frame = self.bounds;
//        self.contentView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]

    



这是我的 TableviewController

        // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int 
        // #warning Incomplete implementation, return the number of sections
        return 1
    

    override func tableView(tableView: UITableView,
                            numberOfRowsInSection section: Int) -> Int 
        return imageModel.count
    

    override func tableView(tableView: UITableView,
                            cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 

        let cell = tableView.dequeueReusableCellWithIdentifier("Cell",
                                                               forIndexPath: indexPath) as! TableViewCell

        cell.txtView.text = txtArray[indexPath.row]

        return cell
    

    override func tableView(tableView: UITableView,
                            willDisplayCell cell: UITableViewCell,
                                            forRowAtIndexPath indexPath: NSIndexPath) 

        guard let tableViewCell = cell as? TableViewCell else  return 

        tableViewCell.setCollectionViewDataSourceDelegate(self, forRow: indexPath.row)

        tableViewCell.collectionViewOffset = storedOffsets[indexPath.row] ?? 0


    




    override func tableView(tableView: UITableView,
                            didEndDisplayingCell cell: UITableViewCell,
                                                 forRowAtIndexPath indexPath: NSIndexPath) 

        guard let tableViewCell = cell as? TableViewCell else  return 

        storedOffsets[indexPath.row] = tableViewCell.collectionViewOffset
    









extension TableViewController: UICollectionViewDelegate, UICollectionViewDataSource 
    func collectionView(collectionView: UICollectionView,
                        numberOfItemsInSection section: Int) -> Int 

        return imageModel[collectionView.tag].count
    



    func collectionView(collectionView: UICollectionView,
                        cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell 

        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell",
                                                                         forIndexPath: indexPath) as! CollectionViewCell



         cell.imgView.frame = CGRectMake(0, 0, collectionView.frame.width, collectionView.frame.height)

         cell.imgView.contentMode = .ScaleAspectFit


        //cell.addSubview(imageView)

         cell.imgView.image = ResizeImage(UIImage(named: imageModel[collectionView.tag][indexPath.item])!, targetSize: CGSizeMake( cell.imgView.frame.width ,  cell.imgView.frame.height))
        //imageView.image = UIImage(named: imageModel[collectionView.tag][indexPath.item])


        return cell
        


如何根据其中的内容将此集合视图设为AutoLayout 本身?我也试过这个:

    self.tableView.rowHeight = UITableViewAutomaticDimension;
    self.tableView.estimatedRowHeight = 100;

但没有用(我的收藏视图消失了)如果有人知道该怎么做,请指导我..

【问题讨论】:

如果 Collectionview 调整大小工作 tableview 单元格应自行调整大小,以防您放置正确的布局。 Collectionview 不会自动调整大小,有内部布局系统 @Anton 你的意思是我必须单独处理collectionView的布局?? 是的。但是在你的tableview单元格中放置任何对象的laoyut,所以自动demsion应该首先调整单元格的大小 @Anton 你是什么意思?你能详细说明一下吗? UITableViewAutomaticDimension 不适用于错误的单元格布局。现在它没有调整 tebleview 单元格的大小。 【参考方案1】:

当我在表格视图单元格中使用集合视图时,我遇到了类似的问题。无论我做什么,我都无法让表格视图自动调整大小,但集合视图可以。 Soo 而不是自动布局,我使用代码完成了它。

我最终不得不在集合视图中计算集合视图 numberOfSections 中标签的大小,并使用委托将此高度传递给具有 tableView 的委托和 dataSource 的视图控制器,并重新加载表视图的适当行。

碰巧,collectionview 数据源中的 numberOfSections 每次都会被调用,并且委托会调整表格视图高度的大小。 像这样的东西-

-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView

    [self.delegate setViewHeight:[self getHeightForCellAtIndexPath:[NSIndexPath indexPathForRow:currentSelected inSection:0]]];

    return 1;

这应该给你一个大致的想法。

编辑:对不起,我之前误解了你的问题。以下是适合您的内容:

据我了解,您有一个表格视图单元格,其中包含标签视图和集合视图。

现在,在表格视图单元格中,您应该为标签添加顶部、前导和尾部约束空间。现在在您的集合视图中将您的图像垂直放置在中心,并为单元格超级视图添加适当的顶部和底部。您的集合视图本身应该在前导、尾随、顶部到标签和底部到超级视图中具有 CONSTANT 值。还要为您的集合视图添加一个固定的高度约束(假设您希望图像大小保持不变)。

现在让我们说 View Controller A 是表格视图的数据源,表格视图单元格是集合视图的数据源。

在您的 viewController A 中,您应该将 indexPath 处的行的高度写为-

 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    CGSize stringSize = [yourStringArray[indexPath.row] boundingRectWithSize:CGSizeMake(_yourCollectionView.frame.size.width, FLT_MAX)
                                                  options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
                                               attributes:@NSFontAttributeName:[UIFont yourFont size:yourFontSize] context:nil].

    return stringSize.height + 35; //magic number 35, play around with it to suit your need. Did this to always have a minimum fixed height.

这将允许您的 tableViewRowForHeight 为该特定索引添加标签的高度,其余的应该由约束来完成。

【讨论】:

man 这个collectionView的东西真的很痛苦,我希望你的解决方案对我有用,你能详细说明一下吗?/ 嘿@IrLearn 请看我的这个问题***.com/questions/37795158/… @remyboys,是的,确定哪一部分?喜欢如何添加约束或喜欢计算高度或全部?我会适当地编辑我的答案。 (否则它将成为一个大评论)就另一个问题而言,我认为流程布局不会导致崩溃。它应该根据您的错误消息显示一个奇怪的 UI,但我认为它不应该崩溃。 我以前从未使用过 UICollectionView 并且对布局 api 不太了解,所以如果你能提供一个简短的演示或 sn-p 来说明我试图实现的目标,那么它对我有好处@IeLearn跨度> 那里,编辑了评论。这应该对你有用。

以上是关于tableview 的行高没有变化,CollectionView 正在捕获所有未使用的空间,而不是在 tableViewCell 中调整自身大小的主要内容,如果未能解决你的问题,请参考以下文章

如何正确更改 TableView 的行高?

无法更改单元格的行高 - 有 2 个原型单元格

UIWebView 中的行高变化

泰山OFFICE技术讲座:着重号引起的行高变化

泰山OFFICE技术讲座:着重号引起的行高变化

ios11 tableView的reloadSections 方法,刷新显示错乱