pickerview example data array xcode swift uipickerview

xcode - data - uipickerview swift 4 example



¿Cómo usar 2 UIPickerView en un controlador de vista? (5)

Tengo 2 UIPickerController en uno de los controladores de vista. Puedo hacer que una funcione, pero cuando agrego una segunda, mi aplicación falla. Aquí está el código que utilizo para una vista de selector:

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] } }

Ahora, ¿cómo puedo hacer que funcione un segundo controlador? Digamos que mi segundo PickerView se llama location (el otro se llama position ). Intenté duplicar el código dentro de los métodos PickerView para la location pero no funciona.

Estoy usando Swift.


Aquí está mi solución: - en el Guión gráfico, agregue 2 PickerView a su Vista - establezca la primera etiqueta del selector como # 1 y # 2 para el segundo selector bajo el Inspector de Atributos - CTRL + arrastre desde cada selector hasta la parte superior amarilla Ver Haga clic en el icono del controlador y elija dataSource. Repita la misma elección de delegado; repita lo anterior para el otro selector también: agregue pickerview y pickerviewdelegation a su clase ViewController:

class ViewController: UIViewController,UIPickerViewDataSource,UIPickerViewDelegate {

  • en su clase ViewController, cree matrices vacías para los selectores:

    var picker1Options = [] var picker2Options = []

  • En el método viewDidLoad (), rellene los arreglos con su contenido:

    picker1Options = ["Option 1","Option 2","Option 3","Option 4","Option 5"] picker2Options = ["Item 1","Item 2","Item 3","Item 4","Item 5"]

  • implementar los métodos delegado y 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])" } }

Disfruta, diviértete y expresa tu felicidad con un signo de positividad.


Creo que el problema más grande y diferente a Java es que Java permite fácilmente que los atributos se pasen a través del constructor. por ejemplo, puede declarar la clase LocationDataSourceDelegate como genérica y llamarlo genericDataSourceDelegate y hacer que el constructor acepte y Array publique genericDataSourceDelegate (String data []) y pueda hacer una clase donde simplemente podría crear objetos. Simplemente crea una instancia y pasa la ubicación del constructor como genericDataSourceDelegate (ubicación)

El problema con su modelo tendrá que crear tantas clases delegadas en un programa que sea una carga para su compilador.


Encontré esto para trabajar.

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] } } }


Mi fondo es en Android pero mi respuesta es muy buena. Sugeriría crear diferentes clases para implementar DataSource y Delegate así:

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] } }

y luego otro para la Ubicación:

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] } }

entonces en su RegisterJobPosition necesita crear una instancia de cada uno:

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

y asignarlos a los recolectores de esta manera:

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

y puede acceder a la posición y ubicación seleccionadas utilizando:

positionDSD.selectedPosition locationDSD.selectedLocation

Espero que esto te ayude a ti y a otros y también espero algunos comentarios constructivos de por qué esto no es "rápido"


Sobre la base de la información que tengo en la pregunta, diría que necesita configurar la fuente de datos y los métodos de delegación para manejar la capacidad de distinguir entre qué instancia del selector los está llamando.

Usar la propiedad de etiqueta en la vista del selector es una estrategia.

Debería haber algunas instrucciones if / else o switch en los métodos que tienen una lógica variable dependiendo de si se hace referencia a la ubicación o al selector de posición.