如何在一个视图控制器中使用两个UIPickerView?

问题描述 投票:25回答:5

我在一个视图控制器中有两个UIPickerControllers。我可以让一个工作,但当我添加一秒钟,我的应用程序崩溃。这是我用于一个选择器视图的代码:

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的picker视图方法中复制代码,但它不起作用。

xcode swift uipickerview
5个回答
25
投票

根据我在问题中的信息,我要说你需要设置数据源和委托方法来处理区分哪个选择器实例正在调用它们的能力。

选择器视图中的Using the tag property是一种策略。

方法中应该有一些if / else或switch语句具有不同的逻辑,具体取决于它是被引用的位置还是位置选择器。


62
投票

这是我的解决方案:

  • 在故事板中,将两个UIPickerView实例添加到您的视图中
  • 将第一个选择器的标签设置为1,并在“Attributes Inspector”下为第二个选择器设置2
  • 控制+从每个选择器拖动到顶部黄色视图控制器图标,然后选择dataSource。重复选择delegate
  • UIPickerViewDataSourceUIPickerViewDelegate添加到您的视图控制器: 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]
        }
    }
}

0
投票

我的背景是在Android,但我的答案是非常OOP。我建议创建不同的类来实现DataSource和Delegate,如下所示:

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

希望这对你和其他人有所帮助,我也希望能有一些建设性的意见,说明为什么这不是“swifty”


0
投票

我认为与Java不同的最大问题是Java很容易允许通过构造函数传递属性。例如你可以将类LocationDataSourceDelegate声明为泛型并将其称为genericDataSourceDelegate,并使构造函数accept和Array public genericDataSourceDelegate(String data [])并且能够创建一个只能创建对象的类。你只是实例化它并传递像genericDataSourceDelegate(location)这样的构造函数的位置

您的模型存在问题,您必须在一个程序中创建尽可能多的委托类,这对您的编译器来说是一种压力。

© www.soinside.com 2019 - 2024. All rights reserved.