运行时Swift UITableViewCell动态单元格高度

时间:2016-01-11 04:48:33

标签: ios swift uitableview

关于如何设法执行下面的用例的任何想法。虽然我设法使用UITableView执行此操作,但每次滚动table view时仍会遇到问题。

场景:table view需要根据选择的项目动态调整单元格的高度。每个项目内部都有不同的选项。选择选项后,它应该能够显示项目下的选项并自动调整高度。

解决方案:我已将UITableViewUITableViewCell分组。每当选项selected/tapped时,我都会致电beginUpdateendUpdate,这是完美的。

问题:每次用户向下滚动时,选项都无法正确显示。

enter image description here

enter image description here

enter image description here

enter image description here

3 个答案:

答案 0 :(得分:1)

每次向上或向下滚动时,uitableview都会调用cellForRowAtIndexPath,而tableView将重新加载。

因此,在这种情况下,您需要在向上或向下滚动之前跟踪所选的单元格,滚动之后您只需要用所需的单元格替换状态(例如高度)。

在我的情况下,我正在使用一些可靠的来跟踪细胞的高度。

以下是我的代码: -

import UIKit

class WaitingListClass: UIViewController,UITableViewDataSource, UITableViewDelegate {

var selectedCellIndexPath: NSIndexPath!
let SelectedCellHeight: CGFloat = 88.0
let UnselectedCellHeight: CGFloat = 44.0

@IBOutlet weak var tableView: UITableView!

override func viewDidLoad() {
    let appdelegateObjForThisClass = UIApplication.sharedApplication().delegate as! AppDelegate
    tableView.delegate = self
    tableView.dataSource = self
    self.tableView.rowHeight = UITableViewAutomaticDimension
    self.tableView.backgroundColor = UIColor.clearColor()
    self.tableView.separatorColor = tableViewSeperatorColor
    self.tableView.tableFooterView = UIView(frame: CGRectZero)
    self.tableView.contentInset = UIEdgeInsetsZero
}


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



internal func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
    if noDataForTable == true{
        return 1

    }
    return appdelegateObjForThisClass.nameDataForTable.count
}

internal func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
    let cellIdentifier = "WaitingCell"
    let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! CellClassWaitingList
        cell.nameDisplayLbl.text = appdelegateObjForThisClass.nameDataForTable[indexPath.row]["name"]!
        cell.backgroundColor = tableViewCellColor
        cell.nameDisplayLbl.textColor = UIColor(red: 191/255, green: 193/255, blue: 192/255, alpha: 1)
        cell.idDisplayLbl.textColor = UIColor(red: 48/255, green: 143/255, blue: 94/255, alpha: 1)
        cell.idDisplayLbl.text = appdelegateObjForThisClass.indexForTable[indexPath.row]
        cell.userInteractionEnabled = true
        cell.clipsToBounds = true
        cell.selectionStyle = UITableViewCellSelectionStyle.None
        let heightOfCell : CGFloat = self.tableView.delegate!.tableView!(self.tableView, heightForRowAtIndexPath: indexPath)
        if heightOfCell == self.UnselectedCellHeight{
            cell.stackOfBtnInCell.hidden = true
        }else if heightOfCell == self.SelectedCellHeight{
            cell.stackOfBtnInCell.hidden = false
        }
    return cell
}

internal func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let cell  = tableView.cellForRowAtIndexPath(indexPath) as! CellClassWaitingList
    if let selectedCellIndexPath = selectedCellIndexPath {
        if selectedCellIndexPath == indexPath {
            self.selectedCellIndexPath = nil
            UIView.animateWithDuration(0.5, animations: {
                cell.stackOfBtnInCell.hidden = true
                self.view.layoutIfNeeded()
            })
        } else {
            UIView.animateWithDuration(0.5, animations: {
                cell.stackOfBtnInCell.hidden = false
                self.view.layoutIfNeeded()
            })
            self.selectedCellIndexPath = indexPath
        }
    } else {
        UIView.animateWithDuration(0.5, animations: {
            cell.stackOfBtnInCell.hidden = false
            self.view.layoutIfNeeded()
        })
        selectedCellIndexPath = indexPath
    }
    tableView.beginUpdates()
    tableView.endUpdates()
}
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
    let cell  = tableView.cellForRowAtIndexPath(indexPath) as! CellClassWaitingList
    cell.stackOfBtnInCell.hidden = true
}
// MARK: - Cell Separator Setting to Full Size

internal func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    if(self.tableView.respondsToSelector(Selector("setSeparatorInset:"))){
        self.tableView.separatorInset = UIEdgeInsetsZero
    }

    if(self.tableView.respondsToSelector(Selector("setLayoutMargins:"))){
        self.tableView.layoutMargins = UIEdgeInsetsZero
    }

    if(cell.respondsToSelector(Selector("setLayoutMargins:"))){
        cell.layoutMargins = UIEdgeInsetsZero
    }
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    if let selectedCellIndexPath = selectedCellIndexPath {
        if selectedCellIndexPath == indexPath {
            return SelectedCellHeight
        }
    }
    return UnselectedCellHeight
}
}

现在我在这里做的是使用一个名为selectedCellIndexPath的变量,它将首先获取所选单元格的索引路径。接下来我又采取两个名为SelectedCellHeight和UnselectedCellHeight的变量,它通常存储一些高度值,以便在某些情况下相互交换,例如 -

  1. 滚动tableview时。
  2. 选择并取消选择单元格时。
  3. 对于其余的实现,请尝试查看tableView数据源和委托方法。

    谢谢,

    希望这会有所帮助。

答案 1 :(得分:0)

您需要保留单元格状态列表,并在表格视图数据源cellAtIndexPath:heightForCellAtIndexPath:中分别格式化单元格并指定所需的单元格高度。

您可以创建NSMutableSet并添加/删除NSIndexPath个对象,或使用NSMutableDictionary并检查与单元格索引对应的某个键是否具有值。

答案 2 :(得分:0)

你是什么意思"选项没有正确显示"?

另外,我会怎么做:

  1. 通过Storyboard在UITableView中创建另一个UITableViewCell。 TableView单元格具有您需要的自定义高度。
  2. 创建一个新的UITableViewCell类文件。
  3. 将新班级分配给情节提要中的单元格。
  4. 按下“选项”时调用TableView.reloadData()。并将所选单元格的Bool设置为true。
  5. 在cellForRowAtIndexPath()中,当Bool为true时,使用自定义UITableViewCell类。