Как получить индекс определенного значения из pickerview?

#json #swift #sorting

#json #swift #сортировка

Вопрос:

Мое приложение пытается показать рейтинг заражения covid (covid19api.com ) страны. У меня есть pickerview для выбора страны и основной информации о covid. Я отсортировал базу данных по количеству заражений. Мой вопрос в том, как получить индексированное значение отсортированного массива для базы стран при выборе pickerview?

Пытался использовать «firstIndex», но выдает следующую ошибку: для ссылки на операторную функцию ‘==’ в ‘StringProtocol’ требуется, чтобы ‘BasicCovidInfoParams’ соответствовал ‘StringProtocol’

Ниже приведен код для проекта:

 struct BasicCovidInfo: Decodable {
    var Countries: [BasicCovidInfoParams]
}
struct BasicCovidInfoParams: Decodable {
    var Country: String?
    var NewConfirmed: Int?
    var TotalConfirmed: Int?
    var NewDeaths: Int?
    var TotalDeaths: Int?
    var NewRecovered: Int?
    var TotalRecovered: Int?
    var Date: String?
}


class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
     
    //var basiccountrycovidinfo = BasicCovidInfoParams()
    var basiccountrycovidinfo = [BasicCovidInfoParams]()
    
    @IBOutlet weak var rankFirstLbl: UILabel!
    @IBOutlet weak var rankSecondLbl: UILabel!
    @IBOutlet weak var rankThirdLbl: UILabel!
    @IBOutlet weak var rankingLbl: UILabel!
    
    
    @IBOutlet weak var covid19CountryPicker: UIPickerView!
    @IBOutlet weak var totalConfirmedLbl: UILabel!
    @IBOutlet weak var totalDeathsLbl: UILabel!
    @IBOutlet weak var totalRecoverdLbl: UILabel!
    @IBOutlet weak var toDateLbl: UILabel!
    
   
    override func viewDidLoad() {
        super.viewDidLoad()

        covid19CountryPicker.delegate = self
        covid19CountryPicker.dataSource = self
        
        getRemoteCovidJsonFile()
        
    }
    
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return basiccountrycovidinfo.count
    }
    
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        
        let numberFormatter = NumberFormatter()
        numberFormatter.numberStyle = NumberFormatter.Style.decimal
        totalConfirmedLbl.text = numberFormatter.string(from: NSNumber(value: basiccountrycovidinfo[row].TotalConfirmed!))
        totalDeathsLbl.text = numberFormatter.string(from: NSNumber(value: basiccountrycovidinfo[row].TotalDeaths!))
        totalRecoverdLbl.text = numberFormatter.string(from: NSNumber(value: basiccountrycovidinfo[row].TotalRecovered!))
        
        
        let dataString = String(basiccountrycovidinfo[row].Date!)
        let from = dataString.index(dataString.startIndex, offsetBy:0)
        let to = dataString.index(dataString.startIndex, offsetBy:10)
        let newString = String(dataString[from..<to])
        //print(newString)
        toDateLbl.text = "Last Update : "   newString

        return basiccountrycovidinfo[row].Country
    }

    
    func getRemoteCovidJsonFile() {
        
        //Info source = "https://api.covid19api.com/summary"
        if let jsonUrlString = URL(string: "https://api.covid19api.com/summary") {
            URLSession.shared.dataTask(with: jsonUrlString) { [self] (data, response, error) in
                
                if let data = data {
                    do {
                        let decoder = JSONDecoder()
                        //decoder.keyDecodingStrategy = .convertFromSnakeCase
                        let covidDataInfo = try decoder.decode(BasicCovidInfo.self, from: data)
                        //print(covidDataInfo.Countries[1].Country!)
                        self.basiccountrycovidinfo = covidDataInfo.Countries
                        
                        let array1 = covidDataInfo.Countries.sorted { (a, b) -> Bool in
                            return a.TotalConfirmed! > b.TotalConfirmed!
                        }

                        let selectedText = pickerView(covid19CountryPicker, titleForRow: 0, forComponent: 0)
                        if let indexOfSelectedText = array1.firstIndex{$0 == selectedText!} {
                            print(array1[indexOfSelectedText])
                        }
               
                        DispatchQueue.main.async {
                            rankFirstLbl.text = array1[0].Country
                            rankSecondLbl.text = array1[1].Country
                            rankThirdLbl.text = array1[2].Country
                    
                            covid19CountryPicker.reloadAllComponents()
        
                        }
                        
                    } catch {
                        print(error.localizedDescription)
                    }
                }
                
            }.resume()
        }

    }
 
}
  

Комментарии:

1. Ваш код отображается нормально при загрузке ваших данных и предоставляет !несортированный! версия для UIPicker для отображения. Тогда все идет наперекосяк. Прежде чем предоставлять данные UIPicker, вы, похоже, пытаетесь извлечь какой-то выделенный текст, который не даст ничего полезного. Затем вы устанавливаете некоторые метки очень нескоординированным образом из своего отсортированного массива. Я думаю , вы хотите дождаться действия UIPickers и установить свои метки с указанием сведений о выбранной стране, но вы не понимаете, как работает UIPicker. Пожалуйста, ознакомьтесь с его документацией и предоставьте ей отсортированные данные.

Ответ №1:

Вы можете использовать selectedRow функцию UIPickerView для получения выбранной строки. Проверьте документацию здесь

 func selectedRow(inComponent component: Int) -> Int
  

Как только вы получите выбранное значение индекса picker, вы можете извлечь значение из массива, используя свойство index.

Комментарии:

1. Большое вам спасибо. Ваше предложение заставило меня изменить подход. Я изменил подход, сначала отсортировав его, прежде чем назначить его pickerview.