UITableView раздел с ячейками - PullRequest
       12

UITableView раздел с ячейками

0 голосов
/ 10 февраля 2019

Я пытаюсь сделать что-то вроде this , но у меня возникают проблемы с добавлением даты в мое табличное представление.У меня есть база данных Realm с датами (Date), именами (String) и числами (Int).

Я успешно добавил дату в каждый раздел, но у меня возникают проблемы с поиском способов добавления имен ичисла в ячейках.Есть несколько строк с одинаковой датой, но с разными именами и номерами.

Пока мой код:

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
    }
}

Ответы [ 2 ]

0 голосов
/ 10 февраля 2019

Что вам нужно сделать, это сгруппировать данные по дате

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 стоит дорого, поэтому вы можете вместо этого сделать это свойство экземпляра

Пример работоспособности ....

Example

//
//  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)
  }
}
0 голосов
/ 10 февраля 2019

Вы можете использовать эти две предопределенные функции.

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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...