在swift中轻点扩展和收缩tableview单元格

时间:2015-08-04 19:57:46

标签: swift uitableview

我正在尝试在点击时展开tableview单元格。然后,当再次点击它时,我希望它恢复到原始状态。

如果cellA被扩展并且tapB被轻击,我希望cellA收缩并且cellB同时扩展。这样在任何给定时刻只有一个细胞可以处于扩张状态。

我目前的代码:

class MasterViewController: UITableViewController {
   var isCellTapped = false
   var currentRow = -1


   override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        selectedRowIndex = indexPath
        tableView.beginUpdates()
        tableView.endUpdates()
    }


   override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

    if indexPath.row == selectedRowIndex.row {
        if isCellTapped == false {
            isCellTapped = true
            return 140
        } else if isCellTapped == true {
            isCellTapped = false
            return 70
        }

    }

    return 70
}

当前代码适用于:

  • 您点按一行(展开)
  • 你再次点击它(它收缩)

在以下时间失败:

  • 您点按一行(展开)
  • 您点按另一行(它收缩,但另一行不会展开)

我该如何解决这个问题?

3 个答案:

答案 0 :(得分:27)

您需要考虑在点击其他行时需要更新所选行,请参阅以下代码:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

    if indexPath.row == selectedRowIndex {
        return 140
    }
    return 44
}

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    if selectedRowIndex != indexPath.row {

        // paint the last cell tapped to white again
        self.tableView.cellForRowAtIndexPath(NSIndexPath(forRow: self.selectedRowIndex, inSection: 0))?.backgroundColor = UIColor.whiteColor()

        // save the selected index 
        self.selectedRowIndex = indexPath.row

        // paint the selected cell to gray
        self.tableView.cellForRowAtIndexPath(indexPath)?.backgroundColor = UIColor.grayColor()

        // update the height for all the cells
        self.tableView.beginUpdates()
        self.tableView.endUpdates()
    }
}
  

修改

要处理选中并再次点击的单元格返回其原始状态,您需要检查以下条件:

var thereIsCellTapped = false
var selectedRowIndex = -1

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

    if indexPath.row == selectedRowIndex && thereIsCellTapped {
        return 140
    }

    return 44
}

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    self.tableView.cellForRowAtIndexPath(indexPath)?.backgroundColor = UIColor.grayColor()

    // avoid paint the cell is the index is outside the bounds
    if self.selectedRowIndex != -1 {
        self.tableView.cellForRowAtIndexPath(NSIndexPath(forRow: self.selectedRowIndex, inSection: 0))?.backgroundColor = UIColor.whiteColor()
    }

    if selectedRowIndex != indexPath.row {
        self.thereIsCellTapped = true
        self.selectedRowIndex = indexPath.row
    }
    else {
        // there is no cell selected anymore
        self.thereIsCellTapped = false
        self.selectedRowIndex = -1
    }

    self.tableView.beginUpdates()
    self.tableView.endUpdates()
}

通过对didSelectRowAtIndexPathheightForRowAtIndexPath函数进行上述修改,您可以看到当单元格被点击其背景颜色时,当它的高度增长时以及当另一个单元格时,它将变为灰色点击该单元格被涂成白色,并轻敲为灰色,一次又一次只允许点击一个单元格。

我虽然您可以在我创建的repo中受益并学习如何操作手风琴菜单,并且我计划很快更新以处理更好的结果,它是使用UITableView处理就像你想要的那样。

您可以在此处发布存储库中的任何疑问。

我希望这对你有所帮助。

答案 1 :(得分:4)

一次只扩展一个单元格的简单方法:

Swift 3

class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {  

var selectedRowIndex = -1  
@IBOutlet weak var tableView: UITableView!

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if indexPath.row == selectedRowIndex {
            return 90 //Expanded
        }
        return 40 //Not expanded
    }

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if selectedRowIndex == indexPath.row {
            selectedRowIndex = -1
        } else {
            selectedRowIndex = indexPath.row
        }
        tableView.reloadRows(at: [indexPath], with: .automatic)
    }
}  

此代码将展开单击的单元格并使用动画关闭先前打开的单元格。

答案 2 :(得分:0)

UITableViewCell

import UIKit

protocol HierarchyTableViewCellDelegate {
   func didTapOnMoreButton(cell:HierarchyTableViewCell)
}

class HierarchyTableViewCell: UITableViewCell {

@IBOutlet weak var viewBtn: UIButton!

//MARK:- CONSTANT(S)
var delegate:HierarchyTableViewCellDelegate!

override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
}
@IBAction func actionViewButtonTapped(_ sender: Any) {
     delegate.didTapOnMoreButton(cell: self)
 }
}

UIViewController:

import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

@IBOutlet weak var tableViewObj: UITableView!
var HierarchyListArr = NSArray()
var selectedIndex:Int?

func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableViewObj.dequeueReusableCell(withIdentifier: "HierarchyTableViewCell", for: indexPath) as! HierarchyTableViewCell
    cell.delegate = self
 if let index = selectedIndex,indexPath.row == index{
        cell.viewBtn.isSelected = true
    }else{
        cell.viewBtn.isSelected = false
    }

    return cell
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if let index = selectedIndex,indexPath.row == index{
        return 190
    }
    return 80
}
}

extension ViewController: HierarchyTableViewCellDelegate{
func didTapOnMoreButton(cell: HierarchyTableViewCell) {
    guard let index = tableViewObj.indexPath(for: cell)else{return}
    if selectedIndex == index.row{
        selectedIndex = -1
    }else{
        selectedIndex = index.row
    }
    tableViewObj.reloadRows(at: [index], with: .fade)
}
}