【问题标题】:UITableView section with cells带有单元格的 UITableView 部分
【发布时间】:2019-02-09 22:24:16
【问题描述】:

我正在尝试制作类似this 的东西,但我无法将日期添加到我的表格视图中。我有一个带日期(日期)、名称(字符串)和数字(整数)的领域数据库。

我已成功将日期添加到每个部分,但我无法找出如何将名称和数字添加到单元格。有多行日期相同,但名称和编号不同。

这是我目前的代码:

import UIKit
import RealmSwift

class myViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!

    var data:Results<Objects>!
    var result:[Objects] = []

    let cellSpacingHeight: CGFloat = 5

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.delegate = self
        tableView.dataSource = self

        retreiveData()
    }

    func retreiveData() {
        let realm = try! Realm()

        // Retreive data
        self.data = realm.objects(Objects.self).sorted(byKeyPath: "date",ascending: false)
        self.result = Array(self.data)

        print(result)

        tableView.reloadData()
    }

    // MARK: - Table View delegate methods

    func numberOfSections(in tableView: UITableView) -> Int {
        return self.result.count
    }

    // Set the spacing between sections
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return cellSpacingHeight
    }

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

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)


        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "EEEE - dd.MM.yyyy"

        let stringGivenDate = dateFormatter.string(from: result[indexPath.section].date!)

        cell.textLabel?.text = "\(stringGivenDate)"
        cell.detailTextLabel?.text = "\(result[indexPath.section].name!)"

        return cell
    }
}

【问题讨论】:

  • 也许我错过了阅读这篇文章,但也许​​您应该首先按日期将数据分组到字典中,这意味着每个“键”将成为一个部分,您可以确定通过那个“键”行。也许首先要弄清楚如何做到这一点 - for example

标签: ios swift realm


【解决方案1】:

您需要做的是按日期对数据进行分组

let grouped: [Data: [Objects]]!

//...
self.result = Array(self.data)
grouped = Dictionary(grouping: result) { (element) -> Date in
    return element.date
}

这将生成一个字典,将具有相同Date 的所有元素分组。现在,您可能需要做一些额外的决策,例如,只按月和年对它们进行分组。

一旦你有了这个,你基本上就拥有了表的结构(部分是字典键和键后面的行数据。

为了说服,我可能还包括...

sections = grouped.keys.sorted()

以更快地按指定顺序访问密钥。

那么您只需将适当的数据应用到您的委托...

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

  // Set the spacing between sections
  func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return cellSpacingHeight
  }

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

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

    let rows = grouped[sections[indexPath.section]]!
    let row = rows[indexPath.row]

    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "EEEE - dd.MM.yyyy"

    let stringGivenDate = dateFormatter.string(from: row.date!)

    cell.textLabel?.text = "\(stringGivenDate)"
    cell.detailTextLabel?.text = "\(row.name!)"

    return cell
  }

  func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    let date = sections[section]

    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "EEEE - dd.MM.yyyy"

    return dateFormatter.string(from: date)
  }

附带说明,DateFormatter 很昂贵,因此您可以考虑将其设为实例属性

可运行示例....

//
//  ViewController.swift
//  QuickTest
//
//  Created by Shane Whitehead on 10/2/19.
//  Copyright © 2019 Swann Communications. All rights reserved.
//

import UIKit

struct Stuff: CustomDebugStringConvertible {
  let date: Date
  let name: String

  var debugDescription: String {
    return "\(date) = \(name)"
  }
}

extension Date {
  static func random(daysBack: Int)-> Date {
    let day = arc4random_uniform(UInt32(daysBack))+1
    let hour = arc4random_uniform(23)
    let minute = arc4random_uniform(59)

    let today = Date(timeIntervalSinceNow: 0)
    let calendar  = Calendar.current
    var offsetComponents = DateComponents()
    offsetComponents.day = -Int(day)
    offsetComponents.hour = Int(hour)
    offsetComponents.minute = Int(minute)

    let randomDate = calendar.date(byAdding: offsetComponents, to: today)
    return randomDate!
  }

  var startOfDay: Date {
    let calendar  = Calendar.current
    return calendar.startOfDay(for: self)
  }
}

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

  @IBOutlet weak var tableView: UITableView!

  let cellSpacingHeight: CGFloat = 5

  var grouped: [Date: [Stuff]] = [:]
  var sections: [Date] = []

  var headerDateFormatter: DateFormatter = {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "MMM yyyy"
    return dateFormatter
  }()

  var cellDateFormatter: DateFormatter = {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "EEEE - dd.MM.yyyy"
    return dateFormatter
  }()

  override func viewDidLoad() {
    super.viewDidLoad()

    retreiveData()

    tableView.delegate = self
    tableView.dataSource = self

    tableView.rowHeight = UITableView.automaticDimension
    tableView.sectionHeaderHeight = UITableView.automaticDimension
    tableView.estimatedRowHeight = 44
    tableView.estimatedSectionHeaderHeight = 44

    tableView.reloadData()
  }

  func retreiveData() {
    var data: [Stuff] = []
    for index in 0..<100 {
      let stuff = Stuff(date: Date.random(daysBack: 10), name: "\(index)")
      data.append(stuff)
    }

    grouped = Dictionary(grouping: data) { (element) -> Date in
      return element.date.startOfDay
    }
    sections = grouped.keys.sorted()

  }

  // MARK: - Table View delegate methods

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

  // Set the spacing between sections
//  func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
//    return cellSpacingHeight
//  }

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

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

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

    let rows = grouped[sections[indexPath.section]]!
    let row = rows[indexPath.row]

    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "EEEE - dd.MM.yyyy"

    let stringGivenDate = dateFormatter.string(from: row.date)

    cell.textLabel?.text = "\(stringGivenDate)"
    cell.detailTextLabel?.text = "\(row.name)"

    return cell
  }

  func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    let date = sections[section]
    return headerDateFormatter.string(from: date)
  }
}

【讨论】:

  • let grouped: [Data, [Workout]! 给了我 2 个错误:数组类型和预期模式中的预期']'。有什么想法吗?
  • @Trinity let grouped: [Data, [Workout]]!
  • 仍然给我同样的错误。我应该在与var result:[Objects] = [] 相同的地方声明这个,对吧?
  • @Trinity var grouped: [Data: [Workout]]! 对不起,我的错?
  • 再次检查,我更新了评论(例如应该是:而不是,
【解决方案2】:

您可以使用这两个预定义的函数。

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return "Section \(section)"
}

override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let view = UIView()
    vw.backgroundColor = UIColor.grey
    return view
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多