Swift 3 - 已展开第一个单元格的可展开表格视图单元格

Posted

技术标签:

【中文标题】Swift 3 - 已展开第一个单元格的可展开表格视图单元格【英文标题】:Swift 3 - Expandable Table View Cells with first cell already expanded 【发布时间】:2017-03-21 15:04:29 【问题描述】:

我正在使用 Swift 3。

我已按照本教程获取它,以便我可以点击表格视图单元格,该单元格将展开以显示更多信息。

https://www.youtube.com/watch?v=VWgr_wNtGPM&t=294s

我的问题是:我该怎么做才能在视图已经加载时展开第一个单元格(即用户不必单击以查看该单元格展开)但所有其他行为保持不变(例如,如果再次点击它,它会崩溃)?

UITableViewCell

import UIKit

class ResultsCell: UITableViewCell 

    @IBOutlet weak var introPara : UITextView!
    @IBOutlet weak var section_heading : UILabel!

    class var expandedHeight : CGFloat  get  return 200.0  
    class var defaultHeight : CGFloat  get  return 44.0  
    var frameAdded = false


    required init?(coder aDecoder: NSCoder) 
        super.init(coder: aDecoder)
    

    override func awakeFromNib() 
        super.awakeFromNib()
        section_heading.translatesAutoresizingMaskIntoConstraints = false
    

    func checkHeight() 
        introPara.isHidden = (frame.size.height < ResultsCell.expandedHeight)
    

    func watchFrameChanges() 
        if(!frameAdded) 
            addObserver(self, forKeyPath: "frame", options: .new, context: nil)
            checkHeight()
        
    

    func ignoreFrameChanges() 
        if(frameAdded)
            removeObserver(self, forKeyPath: "frame")
        
    

    deinit 
        print("deinit called");
        ignoreFrameChanges()
    

    // when our frame changes, check if the frame height is appropriate and make it smaller or bigger depending
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) 
        if keyPath == "frame" 
            checkHeight()
        
    


UITableViewController

// class declaration and other methods above here...

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


// number of rows in the table view
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return section_heading.count


// return the actual view for the cell
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let resultcell = tableView.dequeueReusableCell(withIdentifier: "resultCellTemplate", for: indexPath) as! ResultsCell
    resultcell.section_heading.text = section_heading[indexPath.row]
    resultcell.introPara.attributedText = contentParagraphs[indexPath.row]

    return resultcell


// when a cell is clicked
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    let previousIndexPath = selectedIndexPath

    // the row is already selected, then we want to collapse the cell
    if indexPath == selectedIndexPath 
        selectedIndexPath = nil
     else  // otherwise, we expand that cell
        selectedIndexPath = indexPath
    

    var indexPaths : Array<IndexPath> = []

    // only add a previous one if it exists
    if let previous = previousIndexPath 
        indexPaths.append(previous)
    
    if let current = selectedIndexPath 
        indexPaths.append(current)
    

    // reload the specific rows
    if indexPaths.count > 0 
        tableView.reloadRows(at: indexPaths, with: .automatic)
    


override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) 
    (cell as! ResultsCell).watchFrameChanges()


override func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) 
    (cell as! ResultsCell).ignoreFrameChanges()



override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 
    if indexPath == selectedIndexPath 
        return ResultsCell.expandedHeight
     else 
        return ResultsCell.defaultHeight
    

所以这按预期工作。

但是我怎样才能让第一个单元格已经展开呢?

感谢您的帮助。

【问题讨论】:

【参考方案1】:

我觉得您还没有完全理解自己的代码,但是由于您确实为您的问题付出了很多努力,所以我会给您一个提示。

在顶部某处的 UITableViewController 中初始化 selectedIndexPath,它应该看起来像

var selectedIndexPath: IndexPath?

您可以将其设置为这样的默认值

var selectedIndexPath: IndexPath? = IndexPath(row: 0, section: 0)

因此 (row: 0, section: 0) 处的单元格将默认展开。

【讨论】:

在贴出的代码中,selectedIndexPath 显然是IndexPath 对象,而不是Int 哦,我明白了,我在写答案的时候还没有看到你的帖子。你是对的,它是 IndexPath,但我不想在盘子上给出答案,因为 OP 似乎没有完全理解他自己的代码。 @DonMag 谢谢你!这很有帮助。【参考方案2】:

昨天我参考这个样本完成了类似的功能:https://github.com/justinmfischer/SwiftyAccordionCells

根据您的实施,您正在使用“selectedIndexPath”跟踪当前展开的单元格。因此,当您的视图被加载时,您必须将“selectedIndexPath”行和部分值设置为 0,因为您只使用一个部分。

希望对您有所帮助!

【讨论】:

【参考方案3】:

viewDidLoad 中设置selectedIndexPath = IndexPath(row: 0, section: 0)

这应该“自动扩展”第一行。

【讨论】:

这对我帮助最大。谢谢!【参考方案4】:

看看This,我很久以前就关注了。所以基本上你是在设置一个标志isExpanded:,这样你就可以设置每个单元格是否被消耗。

通过快速谷歌搜索,here 是另一个教程。

【讨论】:

以上是关于Swift 3 - 已展开第一个单元格的可展开表格视图单元格的主要内容,如果未能解决你的问题,请参考以下文章

在 SWIFT 3.0 中展开可选值时意外发现 nil

TableView 使用 Swift 3 展开/折叠

表格行下的可扩展区域(语义 UI 反应)

来自 NIB 的可扩展自定义 UITableViewCell

我们如何快速在表格视图底部添加展开和折叠单元格

UITableviewCell 高度未在滚动时重置