web-dev-qa-db-fra.com

Comment utiliser 2 UIPickerView dans un View Controller?

J'ai 2 UIPickerController dans l'un des contrôleurs de vue. Je peux en faire fonctionner un, mais lorsque j'en ajoute un deuxième, mon application se bloque. Voici le code que j'utilise pour une vue de sélecteur:

import UIKit

class RegisterJobPosition: UIViewController, UIPickerViewDelegate{

@IBOutlet weak var positionLabel: UILabel!

var position = ["Lifeguard", "Instructor", "Supervisor"]

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}    

func numberOfComponentsInPickerView(PickerView: UIPickerView!) -> Int
{
    return 1
}

func pickerView(pickerView: UIPickerView!, numberOfRowsInComponent component: Int) -> Int
{
    return position.count
}

func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String!
{
    return position[row]
}

func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

    positionLabel.text = position[row]
}
}

Maintenant, comment puis-je faire fonctionner un deuxième contrôleur? Supposons que mon deuxième PickerView s'appelle location (l'autre s'appelle position). J'ai essayé de dupliquer le code dans les méthodes PickerView pour location mais cela ne fonctionne pas.

J'utilise Swift.

24
dom999999

D'après les informations que j'ai dans la question, je dirais que vous devez configurer la source de données et les méthodes de délégation pour gérer la possibilité de distinguer entre les instances de sélecteur qui les appellent.

Utiliser la propriété tag sur la vue sélecteur est une stratégie.

Il doit y avoir des instructions if/else ou switch dans les méthodes, dont la logique varie, en fonction de l'emplacement ou du sélecteur de position référencé.

24
andrewcbancroft

Voici ma solution: - sur le Storyboard, ajoutez 2 PickerView à votre vue - définissez la balise du premier sélecteur sur # 1 & # 2 pour le deuxième sélecteur sous l'inspecteur des attributs - CTRL + déplacez chaque sélecteur vers la première icône jaune View Controller et choisissez dataSource. Répétez le même choix de délégué. - Répétez ce qui précède pour l’autre préparateur aussi - ajouter pickerview & pickerviewdelegation à votre classe ViewController:

class ViewController: UIViewController,UIPickerViewDataSource,UIPickerViewDelegate {
  • dans votre classe ViewController, créez des tableaux vides pour les sélecteurs:

    var picker1Options = []
    var picker2Options = []
    
  • sur la méthode viewDidLoad (), remplissez les tableaux avec votre contenu:

    picker1Options = ["Option 1","Option 2","Option 3","Option 4","Option 5"]
    picker2Options = ["Item 1","Item 2","Item 3","Item 4","Item 5"]
    
  • implémenter les méthodes delegate & pickerview:

    func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
        return 1
    }
    
    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        if (pickerView.tag == 1){
            return picker1Options.count
        }else{
            return picker2Options.count
        }
    }
    
    func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
        if (pickerView.tag == 1){
            return "\(picker1Options[row])"
        }else{
            return "\(picker2Options[row])"
        }
    }
    

Profitez, amusez-vous et exprimez votre bonheur avec un signe de positivité.

60
LAOMUSIC ARTS

J'ai trouvé que ça marche.

class SecondViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

    @IBOutlet weak var textbox1: UILabel!
    @IBOutlet weak var textbox2: UILabel!

    @IBOutlet weak var dropdown1: UIPickerView!
    @IBOutlet weak var dropdown2: UIPickerView!

    var age = ["10-20", "20-30", "30-40"]
    var Gender = ["Male", "Female"]

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

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        var countrows : Int = age.count
        if pickerView == dropdown2 {
            countrows = self.Gender.count
        }

        return countrows
    }

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        if pickerView == dropdown1 {
            let titleRow = age[row]
             return titleRow
        } else if pickerView == dropdown2 {
            let titleRow = Gender[row]
            return titleRow
        }

        return ""
    }

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        if pickerView == dropdown1 {
            self.textbox1.text = self.age[row]
        } else if pickerView == dropdown2 {            
            self.textbox2.text = self.Gender[row]
        }
    }
}
2
Diavel Rider

Mon fond est dans Android mais ma réponse est très POO. Je suggérerais de créer différentes classes pour implémenter le DataSource et le délégué comme ceci:

class PositionDataSourceDelegate : NSObject, UIPickerViewDelegate, UIPickerViewDataSource {
   var position = ["Lifeguard", "Instructor", "Supervisor"]
   var selectedPosition : String?

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

    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
      return position.count
    }

    func pickerView(pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
       return position[row]
    }

    func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
       selectedPosition = position[row]
    }
}

et puis un autre pour l'emplacement:

class LocationDataSourceDelegate : NSObject, UIPickerViewDelegate, UIPickerViewDataSource {
   var location = ["Up", "Down", "Everywhere"]
   var selectedLocation : String?

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

    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return location.count
    }

    func pickerView(pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
         return location[row]
    }

    func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        selectedLocation = location[row]
   }
}

ensuite, dans votre RegisterJobPosition, vous devez créer une instance de chaque:

let positionDSD = PositionDataSourceDelegate()
let locationDSD = LocationDataSourceDelegate()

et les assigner aux cueilleurs comme ceci:

positionPicker.dataSource = positionDSD
positionPicker.delegate = positionDSD
locationPicker.dataSource = locationDSD
locationPicker.delegate = locationDSD

et vous pouvez accéder à la position et à la position sélectionnées en utilisant:

positionDSD.selectedPosition 
locationDSD.selectedLocation

J'espère que cela vous aide et aide les autres et j'espère aussi des commentaires constructifs sur les raisons pour lesquelles ce n'est pas "fastueux"

0
Matei Suica

Je pense que le plus gros problème et différent de Java est que Java permet facilement aux attributs de passer par le constructeur. par exemple. vous pouvez déclarer la classe LocationDataSourceDelegate comme générique et l'appeler genericDataSourceDelegate et rendre le constructeur accept et Array public genericDataSourceDelegate (String data []) et pouvoir créer une classe où créer simplement des objets. Vous venez de l'instancier et de transmettre le constructeur comme genericDataSourceDelegate (location)

Le problème avec votre modèle, vous devrez créer autant de classes déléguées dans un programme, ce qui représente une contrainte pour votre compilateur.

0
Dula Al-Zakwani