问题
I have eventsTableView.. here all row are adding one by one no matter what the date is.. but here i need to display tableview according to its date orderedAscending
and the total code is:
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
}
}
this is EventsModel code: like this our model created.. how to sort date from here
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
}
this is 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
}
}
please help me to display tableview row with date ascending order.
回答1:
You need to sort the event array based on the date before reloading tableview. What is the challenge you are facing in doing so?
回答2:
One way to do the sort:
func sort() {
eventList!.events.sort(by: {$0.eventDate < $1.eventDate})
eventsTableView.reloadData()
}
回答3:
Here is a method that you could use to sort your events by date. I've taken a lot of the code that you have out to just focus on how you would go about sorting a custom type like Event
. The first thing you should do is conform to the Comparable
protocol in your EventsModelEvent
class like below (my conformance to CustomStringConvertible
is just to print out the results):
class Event: Comparable, CustomStringConvertible {
It will throw an error and say that this class does not conform to Comparable and this class does not conform to Equatable, would you like to add protocol stubs? Click yes, and it will add the less than (<) and equal to (==) operators as static methods in the class. Since you said that you want them sorted in ascending order you will also need to add greater than (>).
static func < (lhs: Test, rhs: Test) -> Bool {
(code)
}
static func == (lhs: Test, rhs: Test) -> Bool {
(code)
}
static func > (lhs: Event, rhs: Event) -> Bool {
(code)
}
You currently have date being of type String
which won't work when sorting dates. To get around this, add a method to your EventsModelEvent
class to format the date like below. The way you implement this will vary based on how the date is shown in your string, but here is one example:
private func formatDate() -> Date? {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium //Format is Aug 26, 2020
return dateFormatter.date(from: self.date)
}
This will create an optional date from your date property, assuming that you have correctly specified the date format. Now, you said that you wish to compare events based on date, specifically sorted in ascending order. Inside of your comparison methods, you want to return the comparison of the date on the left hand side (las) and the date on the right hand side (res) like below.
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
}
Note that I force unwrapped in this example, so the program would crash if the date returned by formatDate()
was nil. Now you want to add the method to your EventsModel
to sort the Array by date in ascending order and can use the sorted(by:)
method to do so. This is implemented as below.
func sortByDate() -> [Event] {
return events.sorted(by: >)
}
Now if I create an array of Event
like below I can sort it.
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)
prints [one, Jan 1, 1993, two, Dec 31, 2016, three, Aug 16, 2020]
let sortedEvents = events.sortByDate()
print(sortedEvents)
prints [three, Aug 16, 2020, two, Dec 31, 2016, one, Jan 1, 1993]
or more concisely:
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)
Prints [three, Aug 16, 2020, two, Dec 31, 2016, one, Jan 1, 1993]
All classes:
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
}
}
来源:https://stackoverflow.com/questions/63602730/how-to-sort-tableview-rows-according-to-date-ascending-order-in-swift