Подтвердить что ты не робот

Как использовать два 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 но это не работает.

4b9b3361

Ответ 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)

Проблема с вашей моделью должна создать столько классов делегатов в одной программе, которая является напряжением для вашего компилятора.