iosswiftxcodesortingtableview

Sorting cells in table view through buttons


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?

enter image description here

 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?


Solution

  • 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()
    }