I have a table view with data from API. Each cell has several properties. What I want, is to sorting cells by chosen button (these three rectangles).
I dont know exactly how should I do it. I think I need tree methods for that, each for clicked button. But how to deal with sorting and reloading data?
override func viewDidLoad() {
super.viewDidLoad()
callAlamo(url: urlAPI)
}
func callAlamo(url: String){
Alamofire.request(url).responseJSON(completionHandler: {
response in
self.parseData(JSONData: response.data!)
})
}
func parseData(JSONData: Data){
do{
var readableJSON = try JSONSerialization.jsonObject(with: JSONData, options: .mutableContainers) as! JSONStandard
// print(readableJSON)
if let rows = readableJSON["rows"] as? [JSONStandard]{
print(rows)
for i in 0..<rows.count{
let row = rows[i]
if let name = row["name"] as? String{
if name.isEmpty == false{
if let status = row["status"] as? String{
if let counter = row["counter"] as? String{
items.append(Station.init(place: name, counter: counter, status: status))
DispatchQueue.main.async {
self.tableView.reloadData()
}
}else{
let counter = "no data"
items.append(Station.init(place: name, stationsCount: counter, status: status))
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
}
}
}
}
}catch{
print(error)
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! Cell
cell.place.text = items[indexPath.row].place
cell.stationsCount.text = items[indexPath.row].stationsCount
let num = items[indexPath.row].status
let value = picDictionary[num!]
print(num!, value!)
cell.statusSign.image = UIImage(named: value!)
return cell
}
Sometimes I get null value from API, and then, I'm passing value to string "no data".
if let counter = row["counter"] as? String{
/////code
else{
let counter = "no data"
//////
}
And I don't want to let these values taking part in sorting process, because they are not numbers. How to do that?
Make three actions for your three buttons and sort the array with it and reload the table after that.
@IBAction func sortWithName(_ sender: UIButton) {
items.sort { $0.place < $1.place }
self.tableView.reloadData()
}
@IBAction func sortWithStatus(_ sender: UIButton) {
items.sort { $0.status < $1.status }
self.tableView.reloadData()
}
@IBAction func sortWithStatusCount(_ sender: UIButton) {
//stationsCount is looks like number so sort it using compare with numeric option
items.sort { $0.stationsCount.compare($1.stationsCount, options: .numeric) == .orderedAscending }
self.tableView.reloadData()
}
Edit: Declare one more array named allItems
same way you have declared your items array. One more thing I haven't noticed first that you are reloading tableView
inside for loop so that it will reload n(o)
times instead of that you need to reload it once after the for loop also before reloading the tableView
and set allItems
with your items also you are making too many if condition where you can combine it in once.
for row in rows {
if let name = row["name"] as? String,
let status = row["status"] as? String,
!name.isEmpty {
if let counter = row["counter"] as? String {
items.append(Station.init(place: name, counter: counter, status: status))
}else{
let counter = "no data"
items.append(Station.init(place: name, stationsCount: counter, status: status))
}
}
}
//Set allItems with items
self.allItems = items
DispatchQueue.main.async {
self.tableView.reloadData()
}
Now change all your button actions like this.
ke three actions for your three buttons and sort the array with it and reload the table after that.
@IBAction func sortWithName(_ sender: UIButton) {
items = allItems.sorted { $0.place < $1.place }
self.tableView.reloadData()
}
@IBAction func sortWithStatus(_ sender: UIButton) {
items = allItems.sorted { $0.status < $1.status }
self.tableView.reloadData()
}
@IBAction func sortWithStatusCount(_ sender: UIButton) {
//Filter your array first
items = allItems.filter { $0.stationsCount != "no data" }
//stationsCount is looks like number so sort it using compare with numeric option
items.sort { $0.stationsCount.compare($1.stationsCount, options: .numeric) == .orderedAscending }
self.tableView.reloadData()
}