4

我正在尝试构建一些东西(我是 Xcode 和 swift 的新手),我可以在其中使用 Picker View 从数组中选择一天的一餐,并且我希望我的选择显示在特定日期的文本字段中。我有这个工作,但只有 1 天。我怎样才能让这个相同的功能在所有 (7) 天内工作?

当单击下一个文本字段(星期二)时,我也设法获得了选择器视图,但是当我从列表中选择时,星期一文本字段将遵循我在星期二所做的事情。它们是镜像的。我确实知道我可能应该做一些事情来让Tuesday-Picker 以某种方式独一无二,但这就是我坚持的地方。我不知道要更改/写什么。有任何想法的人吗?我用谷歌搜索并找到了很多关于选择器视图的信息,但没有关于如何以这种特定方式使用它们的信息......

//
//  ViewController.swift
//  dropdown
//
//  Created by -- on 2019-08-26.
//  Copyright © 2019 --. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var monday: UITextField!
@IBOutlet weak var tuesday: UITextField!
@IBOutlet weak var wednesday: UITextField!
@IBOutlet weak var thursday: UITextField!
@IBOutlet weak var friday: UITextField!
@IBOutlet weak var saturday: UITextField!
@IBOutlet weak var sunday: UITextField!

// the menu
let Menu = ["Palak Paner",
            "Spagetti Köttfärssås",
            "Thai Haloumi",
            "Thai Quorn",
            "Linssoppa",
            "SparrisPasta",
            "Gröt",
            "Gulasch"]

let tuesdayMenu = ["Palak Paner",
            "Spagetti Köttfärssås",
            "Thai Haloumi",
            "Thai Quorn",
            "Linssoppa",
            "SparrisPasta",
            "Gröt",
            "Gulasch"]


//When a menu from the list is selected, it will be shown as a string

var mondaySelectedMenu: String?
var tuesdaySelectedMenu: String?



override func viewDidLoad() {
    super.viewDidLoad()
    //Call on these functions when loaded
    createMondayMenuPicker()
    createTuesdayMenuPicker()
    createToolbar()
}

// This is the pickerView

func createMondayMenuPicker() {
    let mondayMenuPicker = UIPickerView()
    mondayMenuPicker.delegate = self
    monday.inputView = mondayMenuPicker
}

func createTuesdayMenuPicker() {
    let tuesdayMenuPicker = UIPickerView()
    tuesdayMenuPicker.delegate = self
    tuesday.inputView = tuesdayMenuPicker
}



// This is the "DONE" button
func createToolbar() {
    let toolBar = UIToolbar()
    toolBar.sizeToFit()

    let doneButton = UIBarButtonItem(title: "DONE", style: .plain, target: self, action: #selector(ViewController.dismissKeyboard))
    toolBar.setItems([doneButton], animated: false)
    toolBar.isUserInteractionEnabled = true

    monday.inputAccessoryView = toolBar
    tuesday.inputAccessoryView = toolBar
}


@objc func dismissKeyboard() {
    view.endEditing(true)

}

}


// This is the details for the pickerView
extension ViewController: UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
    return 1
}

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


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

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

    mondaySelectedMenu = Menu[row]
    tuesdaySelectedMenu = tuesdayMenu[row]
    monday.text = mondaySelectedMenu
    tuesday.text = tuesdaySelectedMenu
}



}

所以,我想在点击所有 7 天时调用同一个数组,但我想显示从该列表中选择的每一天的唯一选择。有任何想法吗?非常感谢!

4

3 回答 3

3

实现此目的的一种方法是使用以下方法。我已经将工具栏功能分离到它自己的类中。

创建一个新的类选取器视图的工具栏(在这种情况下,我调用了 ToolbarPickerView.swift)

import UIKit

protocol ToolbarPickerViewDelegate: class {
    func didTapDone()
    func didTapCancel()
}

class ToolbarPickerView: UIPickerView {

    public private(set) var toolbar: UIToolbar?
    public weak var toolbarDelegate: ToolbarPickerViewDelegate?

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.commonInit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.commonInit()
    }

    private func commonInit() {
        let toolBar = UIToolbar()
        toolBar.barStyle = UIBarStyle.default
        toolBar.isTranslucent = true
        toolBar.tintColor = .black
        toolBar.sizeToFit()

        let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(self.doneTapped))
        let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
        let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(self.cancelTapped))

        toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
        toolBar.isUserInteractionEnabled = true

        self.toolbar = toolBar
    }

    @objc func doneTapped() {
        self.toolbarDelegate?.didTapDone()
    }

    @objc func cancelTapped() {
        self.toolbarDelegate?.didTapCancel()
    }
}

在视图控制器中

import UIKit
class ViewController: UIViewController {

    @IBOutlet weak var monday: UITextField!
    @IBOutlet weak var tuesday: UITextField!
    @IBOutlet weak var wednesday: UITextField!
    @IBOutlet weak var thursday: UITextField!
    @IBOutlet weak var friday: UITextField!
    @IBOutlet weak var saturday: UITextField!
    @IBOutlet weak var sunday: UITextField!

    var daysArray = [UITextField]()

    let pickerView = ToolbarPickerView()

    let Menu = ["Palak Paner",
                "Spagetti Köttfärssås",
                "Thai Haloumi",
                "Thai Quorn",
                "Linssoppa",
                "SparrisPasta",
                "Gröt",
                "Gulasch"]

    var selectedMenu : String?

    override func viewDidLoad() {
        super.viewDidLoad()

        setupDelegateForPickerView()
        setupDelegatesForTextFields()
    }

    func setupDelegatesForTextFields() {
        //appending textfields in an array
        daysArray += [monday, tuesday, wednesday, thursday, friday, saturday, sunday]
        //using the array to set up the delegates, inputview for pickerview and also the inputAccessoryView for the toolbar
        for day in daysArray {
            day.delegate = self
            day.inputView = pickerView
            day.inputAccessoryView = pickerView.toolbar
        }
    }

    func setupDelegateForPickerView() {
        pickerView.dataSource = self
        pickerView.delegate = self
        pickerView.toolbarDelegate = self
    }
}

为文本字段委托创建扩展

extension ViewController : UITextFieldDelegate {
    func textFieldDidBeginEditing(_ textField: UITextField) {
        self.pickerView.reloadAllComponents()
    }
}

选择器视图和工具栏的扩展

extension ViewController : UIPickerViewDelegate, UIPickerViewDataSource {
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return self.Menu.count
    }

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

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return self.Menu[row]
    }

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        // Check if the textfield isFirstResponder.
        if monday.isFirstResponder {
            monday.text = self.Menu[row]
        } else if tuesday.isFirstResponder {
            tuesday.text = self.Menu[row]
        } else if wednesday.isFirstResponder {
            wednesday.text = self.Menu[row]
        } else if thursday.isFirstResponder {
            thursday.text = self.Menu[row]
        } else if friday.isFirstResponder {
            friday.text = self.Menu[row]
        } else if saturday.isFirstResponder {
            saturday.text = self.Menu[row]
        } else if sunday.isFirstResponder {
            sunday.text = self.Menu[row]
        } else {
        //log errors
        }
    }
}

extension ViewController: ToolbarPickerViewDelegate {

    func didTapDone() {
//      let row = self.pickerView.selectedRow(inComponent: 0)
//      self.pickerView.selectRow(row, inComponent: 0, animated: false)
//      selectedMenu = self.Menu[row]
        self.view.endEditing(true)
    }

    func didTapCancel() {
       self.view.endEditing(true)
    }
}

PickerView的didSelectRow函数可以通过改成下面来简化

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

        for day in daysArray {
            if day.isFirstResponder {
                day.text = self.Menu[row]
            }
        }
    }

希望这个答案对您有所帮助。

于 2019-09-02T10:26:08.710 回答
0

创建一个通用的选择器类,如下所示:

class PKMultiPicker: UIPickerView, UIPickerViewDelegate, UIPickerViewDataSource {

internal typealias PickerDone = (_ firstValue: String, _ secondValue: String) -> Void
private var doneBlock : PickerDone!

private var firstValueArray : [String]?
private var secondValueArray = [String]()
static var noOfComponent = 2


class func openMultiPickerIn(_ textField: UITextField? , firstComponentArray: [String], secondComponentArray: [String], firstComponent: String?, secondComponent: String?, titles: [String]?, toolBarTint: UIColor = UIColor.black, doneBlock: @escaping PickerDone) {

    let picker = PKMultiPicker()
    picker.doneBlock = doneBlock

    picker.openPickerInTextField(textField, firstComponentArray: firstComponentArray, secondComponentArray: secondComponentArray, firstComponent: firstComponent, secondComponent: secondComponent, toolBarTint: toolBarTint)

    if titles != nil {
        let label = UILabel(frame: CGRect(x: UIScreen.main.bounds.size.width/4 - 10, y: 0, width: 100, height: 30))
        label.text = titles![0].uppercased()
        label.font = UIFont.boldSystemFont(ofSize: 18)
        picker.addSubview(label)

        if PKMultiPicker.noOfComponent > 1 {
            let label = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 30))
            label.text = titles![1].uppercased()
            label.font = UIFont.boldSystemFont(ofSize: 18)
            picker.addSubview(label)
        } else {
            label.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 30)
            label.textAlignment = NSTextAlignment.center
        }
    }
}

private func openPickerInTextField(_ textField: UITextField?, firstComponentArray: [String], secondComponentArray: [String], firstComponent: String?, secondComponent: String?, toolBarTint: UIColor = UIColor.black) {

    firstValueArray  = firstComponentArray
    secondValueArray = secondComponentArray

    self.delegate = self
    self.dataSource = self


    let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(pickerCancelButtonTapped))
    cancelButton.tintColor = toolBarTint
    let doneButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.done, target: self, action: #selector(pickerDoneButtonTapped))
    doneButton.tintColor = toolBarTint
    let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action:nil)

    let toolbar = UIToolbar()
    toolbar.sizeToFit()
    let array = [cancelButton, spaceButton, doneButton]
    toolbar.setItems(array, animated: true)
    toolbar.backgroundColor = UIColor.lightText

    textField?.inputView = self
    textField?.inputAccessoryView = toolbar

    let index = self.firstValueArray?.index(where: {$0.lowercased() == (firstComponent ?? "").lowercased() })
    self.selectRow(index ?? 0, inComponent: 0, animated: true)


    if PKMultiPicker.noOfComponent > 1 {
        let index1 = self.secondValueArray.index(where: {$0.lowercased() == (secondComponent ?? "").lowercased() })
        self.selectRow(index1 ?? 0, inComponent: 1, animated: true)
    }
}

@IBAction private func pickerCancelButtonTapped(){
    UIApplication.shared.keyWindow?.endEditing(true)
}

@IBAction private func pickerDoneButtonTapped(){

    UIApplication.shared.keyWindow?.endEditing(true)

    let index1 : Int?
    let firstValue : String?
    index1 = self.selectedRow(inComponent: 0)

    if firstValueArray?.count == 0{return}
    else{firstValue = firstValueArray?[index1!]}

    var index2 :Int!
    var secondValue: String!
    if PKMultiPicker.noOfComponent > 1 {
        index2 = self.selectedRow(inComponent: 1)
        secondValue = secondValueArray[index2]
    }
    self.doneBlock((firstValue ?? ""), (secondValue ?? ""))
}

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {

    if component == 0 {
        return firstValueArray!.count
    }
    return secondValueArray.count
}

func numberOfComponents(in pickerView: UIPickerView) -> Int {
    return PKMultiPicker.noOfComponent
}


func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {

    switch component {

    case 0:
        return firstValueArray?[row]
    case 1:
        return secondValueArray[row]
    default:
        return ""
    }
}
}

打开选择器和管理选择的示例代码,还有更多选项,您还可以管理组件的数量:-

  PKMultiPicker.noOfComponent = 1
  PKMultiPicker.openMultiPickerIn(textField, firstComponentArray: ["Apple", "Mango","Grapes","Pine apple"], secondComponentArray: [], firstComponent: textField.text, secondComponent: nil, titles: nil, toolBarTint: AppColors.themeGreen) { (firstSelect, secondSelect) in
                        print("first select : \(firstSelect)")
                        textField.text = firstSelect // you can set text here to the respective text field.

                    }
于 2019-09-03T04:06:15.077 回答
0

这里@pawan_kumar 描述了一种对具有相同数据的多个文本字段使用相同选择器视图的方法。但您也可以为此绑定不同的数据源。https://stackoverflow.com/a/60631018/10505343有一个示例代码。在这里,我UITextField.isFirstResponder用来决定应该将哪些数据加载到选择器视图中。希望这个答案也对您有所帮助。

于 2020-03-11T07:29:40.897 回答