Как использовать два UIPickerViews в одном контроллере представления?
У меня есть два UIPickerController
в одном контроллере представления. Я могу заставить один работать, но когда я добавляю секунду, мое приложение вылетает. Вот код, который я использую для одного вида выбора:
import UIKit
class RegisterJobPosition: UIViewController, UIPickerViewDelegate {
@IBOutlet weak var positionLabel: UILabel!
var position = ["Lifeguard", "Instructor", "Supervisor"]
override func viewDidLoad() {
super.viewDidLoad()
}
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]
}
}
Теперь, как я могу заставить второго сборщика работать? Скажем, мой второй вид сборщика называется location
(другой называется position
). Я попытался продублировать код в методах просмотра выбора для определения location
но это не работает.
Ответы
Ответ 1
Основываясь на информации, которую я имею в вопросе, я бы сказал, что вам нужно настроить методы источника данных и делегата, чтобы обрабатывать возможность различать, какой экземпляр средства выбора вызывает их.
Использование свойства тега в представлении выбора - одна из стратегий.
Должны быть некоторые операторы if/else или switch в методах, которые имеют различную логику, в зависимости от того, на какую ссылку или указатель местоположения ссылаются.
Ответ 2
Вот мое решение:
- в раскадровке добавьте два экземпляра
UIPickerView
к вашему представлению - установите первый тег сборщика как
1
и установите 2
для второго сборщика под "Инспектором атрибутов" - control + перетащите из каждого средства выбора на верхний желтый значок контроллера представления и выберите
dataSource
. Повторите тот же выбор delegate
-
добавьте UIPickerViewDataSource
и UIPickerViewDelegate
к вашему контроллеру представления:
class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
-
в вашем классе контроллера представления создайте пустые массивы для сборщиков:
var picker1Options = []
var picker2Options = []
-
В viewDidLoad()
заполните массивы своим контентом:
picker1Options = ["Option 1","Option 2","Option 3","Option 4","Option 5"]
picker2Options = ["Item 1","Item 2","Item 3","Item 4","Item 5"]
-
реализовать делегат и методы источника данных:
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])"
}
}
Ответ 3
Я нашел, что это работает.
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]
}
}
}
Ответ 4
Мой фон находится в Android, но мой ответ очень ооп. Я бы предложил создать различные классы для реализации DataSource и делегирования следующим образом:
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]
}
}
а затем еще один для местоположения:
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]
}
}
то в вашем RegisterJobPosition вам нужно создать экземпляр каждого из них:
let positionDSD = PositionDataSourceDelegate()
let locationDSD = LocationDataSourceDelegate()
и назначьте их сборщикам следующим образом:
positionPicker.dataSource = positionDSD
positionPicker.delegate = positionDSD
locationPicker.dataSource = locationDSD
locationPicker.delegate = locationDSD
и вы можете получить доступ к выбранной позиции и местоположению, используя:
positionDSD.selectedPosition
locationDSD.selectedLocation
Надеюсь, это поможет вам и другим, и я также надеюсь на некоторые конструктивные комментарии о том, почему это не "экономно"
Ответ 5
Я думаю, что самая большая проблема и отличие от Java заключается в том, что Java легко позволяет передавать атрибуты через конструктор. например вы можете объявить класс LocationDataSourceDelegate как общий и вызвать его genericDataSourceDelegate и сделать конструктор accept и Array public genericDataSourceDelegate (String data []) и иметь возможность сделать один класс, где можно просто создать объекты. Вы просто создаете экземпляр и передаете местоположение конструктору типа genericDataSourceDelegate (location)
Проблема с вашей моделью должна создать столько классов делегатов в одной программе, которая является напряжением для вашего компилятора.