自动调整(动态高度)tableview单元格的问题

时间:2017-02-17 11:49:09

标签: ios swift xcode autolayout tableview

我在UIViewController中有一个UITableView作为视图的一部分。我试图根据文本的长度自动调整表格单元格。它没有设置textview的文本,并且单元格在idCellTextView-cell的标准高度处结束。我已经四处搜索并试图在单元格内的textview中使用自动布局固定相对于内容视图和代码,如下所示。 :

tableView.estimatedRowHeight = 70
tableView.rowHeight = UITableViewAutomaticDimension

与问题相关的其余视图控制器显示在:

class ExperimentViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextViewDelegate {
var expId: String = ""
let experimentDescription: String = ""
var cellDescriptors: NSMutableArray!
var visibleRowsPerSection = [[Int]]()


let notificationCenter = NotificationCenter.default

override func viewDidLoad() {
    super.viewDidLoad()


    //TABLE CELLS
    loadCellDescriptors()
    tableView.tableFooterView = UIView()
    tableView.layoutMargins = UIEdgeInsets.zero
    tableView.separatorInset = UIEdgeInsets.zero
    tableView.delegate = self
    tableView.dataSource = self
    tableView.isHidden = true
    tableView.estimatedRowHeight = 70
    tableView.rowHeight = UITableViewAutomaticDimension
    tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellIdentifier")
    tableView.register(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "idCellNormal")
    tableView.register(UINib(nibName: "HintCell", bundle: nil), forCellReuseIdentifier: "idCellTextView")


    //ADD VIEWS
    baseView.addSubview(backgroundImage)
    baseView.addSubview(foregroundImage)
    baseView.addSubview(nameLabel)
    baseView.addSubview(segmentedController)
    baseView.addSubview(descriptionText)
    baseView.addSubview(hint)
    baseView.addSubview(tableView)

}



/*
 Get property list for the different cells we want to have in the hint table
 */
func loadCellDescriptors() {
    if let path = Bundle.main.path(forResource: "CellDescriptor", ofType: "plist") {
        cellDescriptors = NSMutableArray(contentsOfFile: path)
        getIndicesOfVisibleRows()
        tableView.reloadData()
    }
}

/*
 Returns number of rows in a given section
 */
func tableView(_ tableView:UITableView, numberOfRowsInSection section:Int) -> Int {
    return visibleRowsPerSection[section].count
}

/*
 Returns number of sections in table
 */
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    /*if cellDescriptors != nil {
        return cellDescriptors.count
    }
    else {
        return 0
    }*/
    print(items.count)
    return 3
}

/*
 Sets up the cell contents
 */
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let currentCellDescriptor = getCellDescriptorForIndexPath(indexPath)
    let cell = tableView.dequeueReusableCell(withIdentifier: currentCellDescriptor["cellIdentifier"] as! String , for: indexPath) as! CustomCell

    if currentCellDescriptor["cellIdentifier"] as! String == "idCellNormal" {
        print("1")
        if currentCellDescriptor["primaryTitle"] != nil {
            cell.labelOfRow.text = "Hintet er"
            cell.accessoryType = UITableViewCellAccessoryType.disclosureIndicator
        }
    } else if currentCellDescriptor["cellIdentifier"] as! String == "idCellTextView" {

        cell.textView.delegate = self
        cell.textView.isEditable = false
        cell.textView.isSelectable = false
        cell.textView.isScrollEnabled = true
        cell.textView.text = "orem Ipsum er rett og slett dummytekst fra og for trykkeindustrien. Lorem Ipsum har vært bransjens standard for dummytekst helt siden 1500-tallet, da en ukjent boktrykker stokket en mengde bokstaver for å lage et prøveeksemplar av en bok. Lorem Ipsum har tålt tidens tann usedvanlig godt, og har i tillegg til å bestå gjennom fem århundrer også tålt spranget over til elektronisk typografi uten vesentlige endringer. Lorem Ipsum ble gjort allment kjent i 1960-årene ved lanseringen av Letraset-ark med avsnitt fra Lorem Ipsum, og senere med sideombrekkingsprogrammet Aldus PageMaker som tok i bruk nettopp Lorem Ipsum for dummytekst.orem Ipsum er rett og slett dummytekst fra og f"
    }
    cell.layoutMargins = UIEdgeInsets.zero

    return cell
}

/*
 Handles row selections
 Finds the index of the cell that was selected, checks if it is/can be expanded and animates in the additional rows
 */
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let indexOfTappedRow = visibleRowsPerSection[indexPath.section][indexPath.row]
    let cellDescriptor = cellDescriptors[indexPath.section] as! NSMutableArray
    let cell = (cellDescriptors[indexPath.section] as! NSMutableArray)[indexOfTappedRow]
    var shouldExpandAndShowSubRows: Bool = false

    //Checks if cell is expandable, if it is we check if cell isn't already expanded. If it isn't we can expand the cell
    if (cell as AnyObject)["isExpandable"] as! Bool == true {
        shouldExpandAndShowSubRows = false
        if (cell as AnyObject)["isExpanded"] as! Bool == false {
            shouldExpandAndShowSubRows = true
        }
    }

    (cell as AnyObject).setValue(shouldExpandAndShowSubRows, forKey: "isExpanded")

    //Makes the cells inside the specific section visible
    for i in (indexOfTappedRow + 1)...(indexOfTappedRow + ((cell as AnyObject)["additionalRows"] as! Int)) {
        (cellDescriptor[i] as AnyObject).setValue(shouldExpandAndShowSubRows, forKey: "isVisible")
    }

    //Update the overview of the currently visible rows
    getIndicesOfVisibleRows()
    //Reload the sections to see the changes
    tableView.reloadSections(NSIndexSet(index: indexPath.section) as IndexSet, with: UITableViewRowAnimation.fade)
}

/*
 Get overview of the rows that are currently visible
 */
func getIndicesOfVisibleRows() {
    visibleRowsPerSection.removeAll()

    for currentSectionCells in cellDescriptors.objectEnumerator().allObjects as! [[[String:AnyObject]]] {
        var visibleRows = [Int]()

        for row in 0...((currentSectionCells).count - 1) {
            if currentSectionCells[row]["isVisible"] as! Bool == true {
                visibleRows.append(row)
            }
        }

        visibleRowsPerSection.append(visibleRows)
    }
}

/*
 Get cell descriptor from file for specific cell
 */
func getCellDescriptorForIndexPath(_ indexPath: IndexPath) -> [String: AnyObject] {
    let indexOfVisibleRow = visibleRowsPerSection[indexPath.section][indexPath.row]
    let cellDescriptor = (cellDescriptors[indexPath.section] as! NSMutableArray)[indexOfVisibleRow] as! [String: AnyObject]
    return cellDescriptor
}
}

4 个答案:

答案 0 :(得分:0)

试试这个 -

确保首先在表格视图单元格中正确添加约束。

然后从故事板的“属性”检查器部分设置UILable的这两个属性:

1 - 行到0

2 - 换行换行

注意 - 不要修复UILable的高度。

对于TextView -

您需要停用滚动。它会起作用。

答案 1 :(得分:0)

您必须将numberOfLines设置为0以允许单元格内的UILabel增长

答案 2 :(得分:0)

试试这个:

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

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

Here Example

答案 3 :(得分:0)

我建议使用AutoLayout而不是自动调整大小。设计UI元素更容易,更好。以下步骤将帮助您,如何使用AutoLayout设计自动调整大小单元格。

设置行高的自动尺寸&估计行高,确保执行以下步骤,自动尺寸对单元格/行高度布局有效。

  • 分配并实施dataSource和委托
  • UITableViewAutomaticDimension分配给rowHeight& estimatedRowHeight
  • 实施委托/数据源方法(即heightForRowAt并向其返回值UITableViewAutomaticDimension

-

@IBOutlet weak var table: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()

    // Don't forget to set dataSource and delegate for table
    table.dataSource = self
    table.delegate = self

   // Set automatic dimensions for row height
    // Swift 4.2 onwards
    table.rowHeight = UITableView.automaticDimension
    table.estimatedRowHeight = UITableView.automaticDimension


    // Swift 4.1 and below
    table.rowHeight = UITableViewAutomaticDimension
    table.estimatedRowHeight = UITableViewAutomaticDimension

}



// UITableViewAutomaticDimension calculates height of label contents/text
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    // Swift 4.2 onwards
    return UITableView.automaticDimension

    // Swift 4.1 and below
    return UITableViewAutomaticDimension
}

用于UITableviewCell中的标签实例

  • 设置行数= 0(& line break mode = truncate tail)
  • 相对于其superview / cell容器设置所有约束(顶部,底部,右侧)。
  • 可选:设置标签的最小高度,如果您希望标签覆盖最小垂直区域,即使标签/文本没有数据。

enter image description here