#swift #date #uitableview
#swift #Дата #uitableview
Вопрос:
У меня есть eventsTableView.. здесь все строки добавляются одна за другой, независимо от даты .. но здесь мне нужно отобразить tableview в соответствии с его датой orderedAscending
и общий код:
class EventsViewController: UIViewController {
var eventList : EventsModel? = nil
@IBOutlet weak var eventsTableView: UITableView!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
getAllEventsList()
}
func getAllEventsList() {
//URLs and code..
do {
let jsonObject = try JSONSerialization.jsonObject(with: data!, options: .mutableLeaves) as! [String :AnyObject]
print("publish event (jsonObject)")
self.eventList = EventsModel.init(fromDictionary: jsonObject)
DispatchQueue.main.async {
if self.eventList?.events.count != 0 {
DispatchQueue.main.async {
self.eventsTableView.reloadData()
}
}
else {
DispatchQueue.main.async {
Constants.showAlertView(alertViewTitle: "", Message: "No Events (self.eventType)", on: self)
self.eventList?.events.removeAll()
self.eventsTableView.reloadData()
}
}
dataTask.resume()
}
}
extension EventsViewController : UITableViewDelegate,UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return eventList?.events.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: EventsTableViewCell = tableView.dequeueReusableCell(withIdentifier: "EventsTableViewCell") as! EventsTableViewCell
let event = eventList!.events[indexPath.row]
if event.isAllDayEvent == true{
cell.eventDate.text = event.eventDate
cell.nameLbl.text = event.eventName
}
else{
cell.cancelLbl.text = ""
cell.nameLbl.text = event.eventName
cell.eventDate.text = event.eventDate
return cell
}
}
это код EventsModel: вот так создана наша модель.. как отсортировать дату отсюда
class EventsModel : NSObject, NSCoding {
var events : [EventsModelEvent]!
init(fromDictionary dictionary: [String:Any]){
events = [EventsModelEvent]()
if let eventsArray = dictionary["Events"] as? [[String:Any]]{
for dic in eventsArray{
let value = EventsModelEvent(fromDictionary: dic)
events.append(value)
}
}
}
func toDictionary() -> [String:Any]
{
var dictionary = [String:Any]()
if events != nil{
var dictionaryElements = [[String:Any]]()
for eventsElement in events {
dictionaryElements.append(eventsElement.toDictionary())
}
dictionary["events"] = dictionaryElements
}
return dictionary
}
это EventsModelEvent
class EventsModelEvent : NSObject, NSCoding {
var eventName : String!
var eventDate: string!
init(fromDictionary dictionary: [String:Any]){
eventName = dictionary["eventName"] as? String
eventDate = dictionary["eventDate"] as? String
}
}
пожалуйста, помогите мне отобразить строку tableview в порядке возрастания даты.
Комментарии:
1. Что такое
EventsModel
? И это структура или класс? Что такоеevents
? Каков форматeventDate
? Вам нужноsort
упорядочить события по дате. Решение зависит от ответов на эти вопросы.2. @vadian спасибо .. отредактировал мой пост с помощью
EventsModel
иEventsModelEvent
3. @vadian.. как отсортировать дату из
EventsModel
4. Вы пытаетесь отсортировать
EventsModelEvent
по дате? Если это так, это должно соответствоватьComparable
протоколу, чтобы Swift знал, как его отсортировать. Что, вероятно, означает, что вам нужно будет преобразовать свойство date изString
вDate
, по крайней мере временно для сортировки, чтобы оно сортировалось так, как вам нужно.
Ответ №1:
Вам необходимо отсортировать массив событий на основе даты перед перезагрузкой tableview. С какой проблемой вы сталкиваетесь при этом?
Комментарии:
1. я отредактировал свой пост с помощью model.. пожалуйста, взгляните .. как отсортировать дату по модели
Ответ №2:
Один из способов выполнить сортировку:
func sort() {
eventList!.events.sort(by: {$0.eventDate < $1.eventDate})
eventsTableView.reloadData()
}
Ответ №3:
Вот метод, который вы могли бы использовать для сортировки ваших событий по дате. Я использовал большую часть имеющегося у вас кода, чтобы просто сосредоточиться на том, как вы будете сортировать пользовательский тип, например Event
. Первое, что вы должны сделать, это соответствовать Comparable
протоколу в вашем EventsModelEvent
классе, как показано ниже (мое соответствие CustomStringConvertible
— просто распечатать результаты):
class Event: Comparable, CustomStringConvertible {
Он выдаст ошибку и скажет, что этот класс не соответствует Comparable, а этот класс не соответствует Equatable, вы хотели бы добавить заглушки протокола? Нажмите да, и он добавит операторы меньше (<) и равно (==) в качестве статических методов в классе. Поскольку вы сказали, что хотите, чтобы они были отсортированы в порядке возрастания, вам также нужно будет добавить больше, чем (>).
static func < (lhs: Test, rhs: Test) -> Bool {
(code)
}
static func == (lhs: Test, rhs: Test) -> Bool {
(code)
}
static func > (lhs: Event, rhs: Event) -> Bool {
(code)
}
В настоящее время у вас есть тип date String
, который не будет работать при сортировке дат. Чтобы обойти это, добавьте метод в свой EventsModelEvent
класс для форматирования даты, как показано ниже. Способ реализации этого будет зависеть от того, как дата отображается в вашей строке, но вот один пример:
private func formatDate() -> Date? {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium //Format is Aug 26, 2020
return dateFormatter.date(from: self.date)
}
Это создаст необязательную дату из вашего свойства date, предполагая, что вы правильно указали формат даты. Теперь вы сказали, что хотите сравнить события на основе даты, в частности, отсортированных в порядке возрастания. Внутри ваших методов сравнения вы хотите вернуть сравнение даты с левой стороны (las) и даты с правой стороны (res), как показано ниже.
static func < (lhs: Event, rhs: Event) -> Bool {
return lhs.formatDate()! < rhs.formatDate()!
}
static func > (lhs: Event, rhs: Event) -> Bool {
return lhs.formatDate()! > rhs.formatDate()!
}
static func == (lhs: Event, rhs: Event) -> Bool {
return lhs.name == rhs.name
}
Обратите внимание, что в этом примере я принудительно развернул, поэтому программа завершилась бы сбоем, если бы дата, возвращенная formatDate()
, была нулевой. Теперь вы хотите добавить метод в свой EventsModel
для сортировки массива по дате в порядке возрастания и можете использовать sorted(by:)
метод для этого. Это реализовано следующим образом.
func sortByDate() -> [Event] {
return events.sorted(by: >)
}
Теперь, если я создам массив Event
, подобный приведенному ниже, я смогу его отсортировать.
let events = Events(events: [Event(name: "one", date: "Jan 1, 1993"), Event(name: "two", date: "Dec 31, 2016"), Event(name: "three", date: "Aug 16, 2020")])
print(events)
печатает [один, 1 января 1993 года, два, 31 декабря 2016 года, три, 16 августа 2020 года]
let sortedEvents = events.sortByDate()
print(sortedEvents)
печатает [три, 16 августа 2020 г., два, 31 декабря 2016 г., один, 1 января 1993 г.]
или более кратко:
let eventsSorted = Events(events: [Event(name: "one", date: "Jan 1, 1993"), Event(name: "two", date: "Dec 31, 2016"), Event(name: "three", date: "Aug 16, 2020")]).sortByDate()
print(eventsSorted)
Печатает [три, 16 августа 2020 г., два, 31 декабря 2016 г., один, 1 января 1993 г.]
Все классы:
class Events: CustomStringConvertible {
var events: [Event]
var description: String {
return events.description
}
func sortByDate() -> [Event] {
return events.sorted(by: >)
}
init(events: [Event]) {
self.events = events
}
}
class Event: Comparable, CustomStringConvertible {
var description: String {
return "(name), (date)"
}
var name: String
var date: String
private func formatDate() -> Date? {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
return dateFormatter.date(from: self.date)
}
static func < (lhs: Event, rhs: Event) -> Bool {
return lhs.formatDate()! < rhs.formatDate()!
}
static func > (lhs: Event, rhs: Event) -> Bool {
return lhs.formatDate()! > rhs.formatDate()!
}
static func == (lhs: Event, rhs: Event) -> Bool {
return lhs.name == rhs.name
}
init(name: String, date: String) {
self.name = name
self.date = date
}
}
Ответ №4:
После добавления в ваш массив выполните сортировку. В приведенном ниже примере сортировка будет от самой новой к самой старой.
class EventsModel : NSObject, NSCoding {
var events : [EventsModelEvent]!
init(fromDictionary dictionary: [String:Any]){
events = [EventsModelEvent]()
if let eventsArray = dictionary["Events"] as? [[String:Any]]{
for dic in eventsArray{
let value = EventsModelEvent(fromDictionary: dic)
events.append(value)
events.sort(by: { $0.date! > $1.date! })
}
}
}
func toDictionary() -> [String:Any]
{
var dictionary = [String:Any]()
if events != nil{
var dictionaryElements = [[String:Any]]()
for eventsElement in events {
dictionaryElements.append(eventsElement.toDictionary())
}
dictionary["events"] = dictionaryElements
}
return dictionary
}
Убедитесь, что вы отсортировали данные перед помещением в ячейку. В противном случае, каждый раз, когда создается ячейка, она будет сортировать данные.