2017-07-20 1 views
0

Dans mon application, j'ai un sélecteur rempli de données de mon serveur après une requête POST.Swift/iOS: l'affichage UIPicker n'est pas actualisé tant que vous n'avez pas tapé après avoir modifié la source de données par programme

Il a initialement un élément (utilisé comme étiquette), et lorsque la requête POST est remplie, la source de données est modifiée et j'appelle picker.reloadAllComponents() pour l'actualiser.

Lorsque cette exécution, rien ne semble se produire à l'écran, le sélecteur ne change pas. Mais une fois tapées, les nouvelles données apparaissent instantanément et cela fonctionne correctement. Il semble que la modification de la source de données fonctionne correctement, mais l'affichage ne change pas jusqu'à ce qu'il soit actualisé.

est-il un moyen de le rafraîchir, ou une autre méthode pour changer la source de données

Voici le code correspondant:

class MyController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource { 

@IBOutlet weak var dossiers_picker: UIPickerView! 
var pickerData: [Dossier] = [Dossier(nom: "Dossier", id: 0)] 
// Dossier is just a tuple class with 2 attributes 

override func viewDidLoad() { 
    super.viewDidLoad() 
    self.dossiers_picker.delegate = self 
    self.dossiers_picker.dataSource = self 
    getDossiers() 
} 

func numberOfComponents(in pickerView: UIPickerView) -> Int { 
    return 1 
} 

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { 
    return pickerData.count 
} 
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { 
    return pickerData[row].nom 
} 

func getDossiers() { 
    ... // Cut the code where I call the server to get the data, etc ... 
    let task = session.dataTask(with: request) { data, response, error in 
     guard let data = data, error == nil else { 
       // check for fundamental networking error 
       print("error=\(String(describing: error))") 
       return 
      } 
     ... // get the data and turn it into an array of Dossier classes in var dossiers 
     self.pickerData = dossiers 
     dossiers_picker.reloadAllComponents() 
    } 
    task.resume() 
} 
} 
+1

Toutes les mises à jour l'interface utilisateur doit être fait sur la file d'attente principale. – rmaddy

+0

Oui, réalisé ceci juste après avoir tapé la question et se sentait stupide ... Merci – Dino

Répondre

0

figured it out lors de l'ajout de la balise asynchrone par rapport à la question ... bon vieux débogage de canard en caoutchouc. Comme le dit @rmaddy, toutes les mises à jour de l'interface utilisateur doivent être effectuées sur le thread principal.

Dans ce cas, remplacez

dossiers_picker.reloadAllComponents() 

avec

DispatchQueue.main.async { 
    self.dossiers_picker.reloadAllComponents() 
} 
+0

@Krunal Je vous vois édité le code pour ajouter "self.", Y a-t-il une différence? Cela fonctionne sans moi dans mon code, donc je suis curieux de savoir si je devrais l'ajouter – Dino