【问题标题】:How to identify first and last rows of each section | Swift如何识别每个部分的第一行和最后一行 |迅速
【发布时间】:2021-12-19 21:58:57
【问题描述】:

如何识别动态表格视图中每个部分的第一行和最后一行,并隐藏单元格类中的视图。

对于每个部分的第一个单元格,我需要隐藏 topView,对于每个部分的最后一行,我需要隐藏 bottomView。

例如我有以下类:

class cell: UITableViewCell {
    @IBOutlet weak var topView: UIView!
    @IBOutlet weak var bottomView: UIView!
    
}

我尝试通过执行以下操作来识别每个部分的最后一行,但它不会隐藏正确的底部视图,除了最后一部分。有没有办法正确识别行?

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! cell
    
    let item = sections[indexPath.section].items[indexPath.row]
    structure = sections[indexPath.section].items
   
    
    let totalRow = tableView.numberOfRows(inSection: indexPath.section)
    
    if(indexPath.row == totalRow - 1)
    {
        cell.bottomView.isHidden = true
    }
    return cell
    
}

var sections = [mySections]()
var structure = [myStructure]()

获取数据:

private func fetchJSON() {
    
    guard let url = URL(string: "test.com")
    else { return }
    
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.httpBody = "id=\1".data(using: .utf8)
    

URLSession.shared.dataTask(with: request) { data, _, error in
guard let data = data else { return }
                
do {
  let decoder = JSONDecoder()
  self.structure.sort { $0. datestamp > $1.datestamp }
  let res = try decoder.decode([myStructure].self, from: data)
  let grouped = Dictionary(grouping: res, by: { $0. datestamp })
  let keys = grouped.keys.sorted()
self.sections = keys.map({mySections(date: $0, items: grouped[$0]!
                    
)})
  DispatchQueue.main.async {
  self.tableView.reloadData()
}
        }
        
        catch {
            print(error)
        }
    }.resume()
 }

结构:

struct mySections {
    let date : String
    var items : [myStructure]
}


struct myStructure: Decodable {
    
    let recordid: Int
    let testname: Int
    let datestamp: String
}

数据示例:

[
  { 
    "recordid": 1,
    "testname": "Jen",
    "datestamp": "2021-11-3"
  },
  {
    "recordid": 1,
    "testname": "Jake",
    "datestamp": "2021-11-2"
  }
]

设置部分:

 override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        let section = sections[section]
        return section.items.count
    }
    
  override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return sections[section].date
    }

【问题讨论】:

  • 可能有更好的方法,但“蛮力”方法是在数据中标记内容。由于表视图是基于数组的,因此只需为其添加一个标志。这样,您还可以使用逻辑重新排序事物以指示更改。让后台数据规则 - 就像它应该的那样。
  • 我明白了,必须有更好的方法来识别这些行的索引路径——我尝试这样做的方式似乎非常接近
  • 接近,但永远不要忘记表格视图是真正基于数据的。你真的没有告诉我们这些数据是什么——但是你的代码能“告诉”表格单元格“嘿,这是本节中的最后一个索引”吗?这样,您的表格单元格代码就不需要弄清楚 - 如果数据要求这样做,它可以简单地隐藏视图。
  • 我想知道是不是只有细胞回收才能吸引你。如果添加一个 else 子句,如果它不是最后一项,则显式将 isHidden 设置为 false 会发生什么?

标签: swift uitableview indexpath


【解决方案1】:

当您在委托中创建单元格时,您正在告诉表格视图它有哪些行和部分。这意味着表格视图还没有完成设置部分,所以现在不是调用tableView.numberOfRows(inSection:) 的合适时间。

您已经从模型中提取了数据...在这种情况下,您的模型看起来有一个部分数组,每个部分都有一个行数组,因此请询问模型您构建的单元格是否位于其部分的开头或结尾:

import UIKit
import SwiftUI
import PlaygroundSupport

class CustomCell : UITableViewCell {
    static let identifier = "CustomCell"
}

class DataSource : NSObject, UITableViewDataSource {
    let sections = [
        [
            "Cow",
            "Duck",
            "Chicken"
        ],

        [
            "Lion",
            "Zebra",
            "Oryx"
        ],
    ]

    func numberOfSections(in tableView: UITableView) -> Int {
        sections.count
    }

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let newCell = tableView.dequeueReusableCell(withIdentifier: CustomCell.identifier, for: indexPath)
        if let cell = newCell as? CustomCell {
            cell.textLabel?.text = sections[indexPath.section][indexPath.row]

            if indexPath.row == 0 {
                cell.textLabel?.backgroundColor = UIColor.yellow
            }

            if indexPath.row == sections[indexPath.section].count - 1 {
                cell.textLabel?.backgroundColor = UIColor.gray
            }
        }

        return newCell
    }
}

let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 320, height: 480))
tableView.register(CustomCell.self, forCellReuseIdentifier: CustomCell.identifier)
let dataSource = DataSource()
tableView.dataSource = dataSource

PlaygroundSupport.PlaygroundPage.current.liveView = tableView

【讨论】:

  • 我得到了,表达式的类型是不明确的,没有以下行的更多上下文:if(indexPath.row == sections[indexPath.section].count - 1) {
  • 如果不知道 sections 是什么,从您发布的内容中无法收集到很多信息。
  • 我还注意到,由于某种原因,每个部分的第二个单元格也隐藏了 topView - 我正在做if(indexPath.row == 0) {
  • 请看我更新的帖子
  • 我用一个完整的操场示例更新了我的答案。它会更改单元格的颜色,但您也可以轻松隐藏视图
猜你喜欢
  • 2015-08-20
  • 2018-12-26
  • 1970-01-01
  • 2015-12-20
  • 1970-01-01
  • 1970-01-01
  • 2016-12-12
  • 2020-03-16
  • 1970-01-01
相关资源
最近更新 更多