高度调整到 TableView 单元格中的内容?

Posted

技术标签:

【中文标题】高度调整到 TableView 单元格中的内容?【英文标题】:Height adjust to content in TableView cell? 【发布时间】:2016-06-16 22:31:01 【问题描述】:

我对 Swift 还很陌生,我偶然发现了一个问题。我获取一些 JSON 数据并将其显示在 TableView 中,但问题是每个单元格可以在彼此下方有 n 个标签(来自 JSON(,因此单元格需要具有不同数量的内容。我该如何实现这一点?

编辑:我真的不能让它工作,我这样做是为了在创建 tableview 时添加更多标签。在我的自定义单元格中。

func addViews() 
     let rect = CGRect(x: 6, y: 10, width: containerView.frame.width-12, height: 90)
     containerView.backgroundColor = UIColor.lightGrayColor()

     let view1 = UIView(frame: rect)
     view1.layer.shadowColor = UIColor.blackColor().CGColor
     view1.layer.masksToBounds = false
     view1.layer.shadowOpacity = 0.2
     view1.layer.shadowOffset = CGSizeMake(-1, 1)
     view1.layer.cornerRadius = 2
     view1.backgroundColor = UIColor.whiteColor()

     var x = 2 as CGFloat
     var y = 2 as CGFloat
     var position = CGPointMake(x, y)
     i in 1...5 
         let recti = CGRect(x: x, y: y, width: 50, height: 50)
         let s = UILabel(frame: recti)
         s.text = "\(i)"
         y = y + 20
         view1.addSubview(s)
         print(i)
     
     containerView.addSubview(view1)  

我已将这两行添加到我的 TableViewController 中

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

但它不会调整,只显示第一个标签,然后再将单元格切断。

【问题讨论】:

【参考方案1】:

在自定义单元格类中设置标签,然后使用cellForRow 向其发送数据。

import UIKit


class cellClass: UITableViewCell 


@IBOutlet weak var containerView: UIView!


func addViews(jsonStuff: [String])

    let rect = CGRect(x: 0, y: 0, width: 100, height: 20)
    var x = 50 as CGFloat
    let y = 20.0 as CGFloat

    var position = CGPointMake(x, y)

    for str in jsonStuff

        let label = UILabel(frame: rect)
        label.text = str
        label.center = position
        containerView.addSubview(label)
        x = x + 40
        //y = y + 20
        position = CGPointMake(x,y)

    












class ViewController: UIViewController, UITableViewDelegate,       UITableViewDataSource 

@IBOutlet weak var table: UITableView!

var stringStuff = ["this", "that", "tje", "blah", "hey"]


override func viewDidLoad() 
    super.viewDidLoad()



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


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

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as!      cellClass
    if indexPath.row < 2
        let sub = stringStuff[0...2]
        cell.addViews(Array(sub))
    else
        cell.addViews(stringStuff)
    


    return cell


func numberOfSectionsInTableView(tableView: UITableView) -> Int 
    return 1



这可能是一个巨大的 hack,我相信还有更好的方法,但这里有一些功能代码可以动态调整行大小,而不使用自动布局或预定义标签。您可能必须使用矩形高度才能使所有内容看起来正确,并且 cellForRowAtIndexPath 中的删除子视图对于单元重用是必需的。

class cellClass: UITableViewCell 

@IBOutlet weak var containerView: UIView!

func addViews(lbsToAdd: Int) 

    let rctHeight = Int((5 + (lbsToAdd * 20)))

    let rect = CGRect(x: 6, y: 10, width: Int(containerView.frame.width-12), height: rctHeight)

    containerView.backgroundColor = UIColor.lightGrayColor()
    let view1 = UIView(frame: rect)
    view1.layer.shadowColor = UIColor.blackColor().CGColor
    view1.layer.masksToBounds = false
    view1.layer.shadowOpacity = 0.2
    view1.layer.shadowOffset = CGSizeMake(-1, 1)
    view1.layer.cornerRadius = 2
    view1.backgroundColor = UIColor.whiteColor()

    let x = 2 as CGFloat
    var y = 0 as CGFloat

    for i in 1...lbsToAdd 
        let recti = CGRect(x: x, y: y, width: 50, height: 20)
        let s = UILabel(frame: recti)
        s.text = "\(i)"
        y = y + 20
        containerView.frame.size.height = containerView.frame.size.height + 20
        view1.addSubview(s)
        print(i)
    

    containerView.addSubview(view1)






class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource 


@IBOutlet weak var testTable: UITableView!

var stringStuff = ["Jetta", "< Golf >", "Passat", "CC", "Beetle", "Ford", "Chevy", "Nissan"]
let labelsCount = 10

override func viewDidLoad() 
    super.viewDidLoad()
    testTable.delegate = self
    testTable.reloadData()


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


func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat 
        let total = ((Int(indexPath.row) + 2) * 2)


        return CGFloat(total * labelsCount)


func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat 
    return UITableViewAutomaticDimension




func numberOfSectionsInTableView(tableView: UITableView) -> Int 
    return 1


func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as? cellClass

    cell?.containerView.subviews.forEach( $0.removeFromSuperview() )


    cell?.addViews(indexPath.row + 1)

    return cell!




【讨论】:

我更好奇如何动态创建标签?我不能只将标签添加到情节提要中的单元格,因为例如,我需要在一个单元格中添加两个标签,在另一个单元格中添加 8 个标签。 在您的自定义单元类中创建一个函数以生成 n 个标签。然后在 for 循环中运行一些这样的代码 var label = UILabel(frame: CGRectMake(0, number, 200, 21)) label.center = CGPointMake(160, 284) label.textAlignment = NSTextAlignment.Center label.text = "I'am a test label" self.view.addSubview(label) 我会试试的!但是我需要根据从 JSON 获得的某些数据的数量创建 n 个标签,在我的自定义单元格类中创建标签时如何获得它? 我已经在上面更新了我的答案,设置约束需要一些患者,但以上是总体思路。在cellForRow 中,您可以放置​​if 语句来决定将哪些数据发送到单元类。这将允许您独立控制每个单元格中的标签数量。 有道理!我会试试看。 @NRitH 没有代码你会怎么做?【参考方案2】:

你不应该在增加 UILabel 后更新 view1 的高度吗,试试这个:

func addViews() 
     let rect = CGRect(x: 6, y: 10, width: containerView.frame.width-12, height: 90)
     containerView.backgroundColor = UIColor.lightGrayColor()



    let view1 = UIView(frame: rect)
     view1.layer.shadowColor = UIColor.blackColor().CGColor
     view1.layer.masksToBounds = false
     view1.layer.shadowOpacity = 0.2
     view1.layer.shadowOffset = CGSizeMake(-1, 1)
     view1.layer.cornerRadius = 2
     view1.backgroundColor = UIColor.whiteColor()
     var containerViewHeight = 0 // height for view1
     var x = 2 as CGFloat
     var y = 2 as CGFloat
     var position = CGPointMake(x, y)

     i in 1...5 
         let recti = CGRect(x: x, y: y, width: 50, height: 50)
         let s = UILabel(frame: recti)
         s.text = "\(i)"
         y = y + 20
         view1.addSubview(s)
         containerViewHeight += 50 //your label height
         print(i)
     
     view1.bounds.size.height = CGFloat(containerViewHeight) // set height
     containerView.addSubview(view1)  

【讨论】:

【参考方案3】:

heightForRowAtIndexPath 中,检查您的 JSON 中的 indexPath 并计算出该单元格所需的高度。然后表格视图将调整行的大小以匹配您的动态内容。

Here is a link to the docs

【讨论】:

【参考方案4】:

UITableViewAutomaticDimension 用于将 UITableViewCell 设置为自动布局。而你没有设置任何。

您有两种通用的方法来实现这一点:

在代码中处理

你知道一个标签需要多少高度,所以在rowForHeightAtIndexPath返回expectedHeightForOneLabel * numberOfLabels

StackView + 自动布局

如果您正在为 ios 9.0+ 开发,请使用 UIStackViewstackView.axis = .Vertical,为您的 stackView 设置 Auto-layout 并设置 stackView.distribution = .FillProportionally,然后开始添加标签。

【讨论】:

以上是关于高度调整到 TableView 单元格中的内容?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 tableview 的单元格中删除 imageView,并重置单元格的高度

TextView的自动高度,在tableView的单元格中使用autolayout

自调整大小表格单元格中的 ImageView 在应用 Aspect Fit 之前使用图像的高度

两个标签在tableView单元格中垂直对齐自动调整大小

为啥自调整大小的表格视图单元格中的 UIImageView 具有内容模式 AspectFit 的原始高度?

Tableview单元格没有动态调整高度