可扩展 UiTableView 的自定义单元格

Posted

技术标签:

【中文标题】可扩展 UiTableView 的自定义单元格【英文标题】:Custom cells for expandable UiTableView 【发布时间】:2018-09-25 09:57:09 【问题描述】:

我有一个包含内部数组的数据集,我必须以展开折叠方式显示该内部数组。

为此,我设计了 2 个 nib 文件。一个用于部分,另一个用于部分中的单元格。

我已经附加了 UtableView 和委托方法。我成功展示了 Header 视图,我正在注册这样的 header 视图。

let nib = UINib.init(nibName: "headerItemSavedListCell", bundle: nil)
self.lvSavedList.register(nib, forCellReuseIdentifier: "headerItemSavedListCell")

对于单元格,我正在使用以下方法

if(indexPath.row == 0)
    let header = Bundle.main.loadNibNamed("headerItemSavedListCell", owner: self, options: nil)?.first as! headerItemSavedListCell

    return header

else

    let cell = Bundle.main.loadNibNamed("ItemSavedListCell", owner: self, options: nil)?.first as! ItemSavedListCell

    return cell

但它不起作用。

**所以我的问题是:**

如何加载内部单元格视图? 如何展开部分内的折叠单元格视图?

如果您有任何关于可扩展 Uitableview 的教程,请提供帮助

【问题讨论】:

你想在点击headerview时折叠单元格 是先展开再折叠 你想一次只打开一个单元格还是什么 是的,打开点击的单元格 【参考方案1】:

我在这里使用的类连接到 xibs

制作视图的xib并绑定到类下面 所以首先你必须像下面这样制作标题视图

protocol HeaderDelegate:class
func didSelectHeader(Header:HeaderFooter,at index:Int)


class HeaderFooter: UITableViewHeaderFooterView 
@IBOutlet weak var lblTitle: UILabel!

weak var delegate:HeaderDelegate?
var Expand = false

override func awakeFromNib() 
    let tap = UITapGestureRecognizer.init(target: self, action: #selector(didSelect(_:)))
    self.addGestureRecognizer(tap)
    self.isUserInteractionEnabled = true


@objc func didSelect(_ tap:UITapGestureRecognizer)

    delegate?.didSelectHeader(Header: self, at: self.tag)


override func prepareForReuse() 
    Expand = false


上面我添加了点击手势来检测 headerViews 上的触摸

接下来制作如下单元格

class ExpandableCell: UITableViewCell 

var isExpanded = false
override func awakeFromNib() 
    super.awakeFromNib()
    isExpanded = false
    // Initialization code


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

    // Configure the view for the selected state



在您的视图控制器中

tblView.register(UINib.init(nibName: "HeaderFooter", bundle: nil), forHeaderFooterViewReuseIdentifier: "HeaderFooter")

在tablview dataSorce 和Delegate 方法中

func numberOfSections(in tableView: UITableView) -> Int 
    return numberofsections


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return numberofrows


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "ExpandableCell") as? ExpandableCell else 
        return UITableViewCell()
    
    //configure cell here
    return cell


func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 
    guard let header = tableView.headerView(forSection: indexPath.section) as? HeaderFooter
        else return 0
    if header.Expand
    
        return UITableViewAutomaticDimension
    
    else
    
        return 0
    


func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat 
    return UITableViewAutomaticDimension

func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat 
     return 50

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 



func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? 
    guard let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "HeaderFooter") as? HeaderFooter else return nil
    //configure header View here
    headerView.tag = section
    return headerView

//MARK:-headerDelegate
func didSelectHeader(Header: HeaderFooter, at index: Int) 
    Header.Expand = !Header.Expand
    //comment below part if you dont want to collapse other rows when other section opened
    for i in 0..<tblView.numberOfSections
    
        if i != index
        
            guard let header = tblView.headerView(forSection: i) as? HeaderFooter else return
            header.Expand = false
            for j in 0..<tblView.numberOfRows(inSection: i)
            
                tblView.reloadRows(at: [IndexPath.init(row: j, section: i)], with: .automatic)
            
        
        else
        
            for j in 0..<tblView.numberOfRows(inSection: i)
            
                tblView.reloadRows(at: [IndexPath.init(row: j, section: i)], with: .automatic)
            
        
    

【讨论】:

让我试试这个 应用程序崩溃并出现错误“无法在包中加载 NIB:HeaderFooter 兄弟添加您的笔尖名称,仅供参考 我添加了。好吧,这个答案并没有帮助我(在添加笔尖并解决错误之后),但不知何故我已经做到了。

以上是关于可扩展 UiTableView 的自定义单元格的主要内容,如果未能解决你的问题,请参考以下文章

UITableView 可重用的自定义单元格在子视图中显示错误的内容

UITableView 仅加载在设备上可见的自定义单元格,并在添加更多单元格时崩溃

使用大型数据库时,如何避免 UITableView 中的自定义单元格加载时间过长

自定义 UITableview 单元格可访问性无法正常工作

如何制作可滑动的 UItableview 标题以显示像单元格一样的删除按钮

UITableview 滚动时有两个不同的自定义单元格重叠