确定哪个 UIPicker 的工具栏按钮发送了消息

Posted

技术标签:

【中文标题】确定哪个 UIPicker 的工具栏按钮发送了消息【英文标题】:Determining which UIPicker's toolbar button sent a message 【发布时间】:2017-03-11 21:25:35 【问题描述】:

我正在尝试在一个页面上使用多个 UIPicker。我想我已经配置了几乎所有东西。当我使用 UIPicker 时,我添加了一个带有“取消”和“完成”按钮的工具栏。

工具栏是使用相同的函数构建的,因此当用户点击“完成”时它会调用相同的操作。下面是一个伪示例流程。

 let pickerData: [String] = ["1", "2", "3", "4"]
 var picker = UIPickerView()
 let pickerData2: [String] = ["A", "B", "C", "D"]
 var picker2 = UIPickerView()

 @IBOutlet weak var textField: UITextField!
 @IBOutlet weak var textField2: UITextField!

override func viewDidLoad() 
  super.viewDidLoad()
  // set up pickers
  setPickerView()
    

// set the pickerview
func setPickerView()
    picker.dataSource = self
    picker.delegate = self
    textField.inputView = picker
    textField.inputAccessoryView = initToolBar()
    // second picker
    picker2.dataSource = self
    picker2.delegate = self
    textField2.inputView = picker
    textField2.inputAccessoryView = initToolBar()


// build the toolbar for uipicker, so a user can select a value
func initToolBar() -> UIToolbar 
    let toolBar = UIToolbar()
    toolBar.barStyle = UIBarStyle.default
    toolBar.isTranslucent = true
    toolBar.tintColor = UIColor(red:14.0/255, green:122.0/255, blue:254.0/255, alpha: 1)
    toolBar.sizeToFit()
    // TODO need to update actions for all buttons
    let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.plain, target: self, action: nil)
    let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.plain, target: self, action: #selector(pickerDoneAction))
    let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
    toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
    toolBar.isUserInteractionEnabled = true

    return toolBar


func pickerDoneAction(sender: UIBarButtonItem)
     /*Here I'm just updating the same textfield when the done button is
       is pressed, I'm not sure how I can get the instance of the picker into this method*/
     let indexPath = picker.selectedRow(inComponent: 0)
     textfield.text = data[indexPath]


// delegates
func numberOfComponents(in pickerView: UIPickerView) -> Int  return 1 
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int 
  if pickerView == picker 
    return pickerData.count
     else return pickerData2.count

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? 
  if pickerView == picker 
    return pickerData[row]
   else return pickerData2[row]

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 
  if pickerView == picker 
    textField.text = pickerData[row]
   else textField2.text = pickerData2[row]

有没有办法确定单击完成按钮时正在使用哪个 UIPicker,所以我可以在我的 pickerDoneAction 方法中使用该实例,然后更改相应文本字段的值?我尝试检查文本字段是否为 firstResponder,甚至尝试检查 UIPicker 本身,但似乎不可能。我需要改变我的方法吗?如果需要,如何改变?

更新 我在现有的UIPicikerView 委托方法中添加了。

澄清一下,我希望在用户按下“完成”时将UIPicker 的值分配给正确的文本字段,因此,如果用户想要从 UIPicker 中选择第一行,它就会被插入。

【问题讨论】:

@downvoter,如果您要投反对票 - 很好,但将其放在评论中会更具建设性,因此可以更正。 是的,或者将pickerview定义为控制器的属性 【参考方案1】:

可以实现如下 UIPickerViewDelegate 的方法:

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

当用户选择组件中的一行并使用时,选择器视图调用该方法的位置

pickerView

(表示请求数据的选取器视图的对象)知道使用了哪个选取器视图。

【讨论】:

为每个pickerView添加一个标签也可能会有所帮助,以获得所选pickerView的字符串表示形式。 我应该在我的pickerDoneAction 中使用didSelectRow 不,只需在您的方法“pickerDoneAction”之上实现该方法 @AlessandroChiarotto 我已经在使用这个功能,但是当用户按下“完成”按钮时不会调用它我不认为,我也将我的问题更新为澄清 使用一个新变量来存储最后一个pickerview或用户使用的最后一个值,然后在你点击完成按钮时使用这个变量【参考方案2】:

您始终可以使用UIViewtag 属性传递数据:

func setPickerView() 
    picker.tag = 1
    textField.inputView = picker
    textField.inputAccessoryView = initToolBar(pickerTag: picker.tag)

    picker2.tag = 2
    textField.inputView = picker2
    textField.inputAccessoryView = initToolBar(pickerTag: picker2.tag)


func initToolBar(pickerTag: Int) 
    let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.plain, target: self, action: #selector(pickerDoneAction))
    doneButton.tag = pickerTag


func pickerDoneAction(sender: UIBarButtonItem)
    let pickerView: UIPickerView

    switch sender.tag 
    case picker.tag:        pickerView = picker
    case picker2.tag:       pickerView = picker2
    default:                return
    

【讨论】:

非常感谢您的帮助。我在链条上走得还不够远,无法把它送过去。您的解决方案很简单而且很好实施。谢谢【参考方案3】:

您可以尝试使用您设置为pickerview的数据源的不同条件动态更改数据

【讨论】:

【参考方案4】:

也许您不需要确定它是哪个选择器,而是确定哪个文本字段。

pickerDoneAction(sender:) 中,使用let textField = sender.superview.superview,其中sender 是按钮,parent 是工具栏,工具栏的parent 是文本字段。然后用pickerData[0] 填充它。

实现相同目标的另一种方法是使用UITextFieldDelegate 的方法textFieldDidEndEditing(_:)。当文本字段结束编辑时,在此处插入默认值。

【讨论】:

当我尝试这个时,我得到一个编译错误,UIBarButtonItem has no member parent 抱歉,应该是superview 而不是parrent。已编辑。 我现在没有 UIBarButtonItem 的成员超级视图 好吧,看起来这行不通。请参阅标准杆的答案,这可能是您最好的选择。【参考方案5】:
let pickerData: [String] = ["1", "2", "3", "4"]
 var picker = UIPickerView()
 let pickerData2: [String] = ["A", "B", "C", "D"]
 var picker2 = UIPickerView() // <<<<<<<<<<<<<
 var userPicker:UIPickerView?

 @IBOutlet weak var textField: UITextField!
 @IBOutlet weak var textField2: UITextField!

.....
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? 
  userPicker = pickerView // <<<<<<<<<<<<<
  if pickerView == picker 
    return pickerData[row]
   else return pickerData2[row]

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 
  userPicker = pickerView // <<<<<<<<<<<<<
  if pickerView == picker 
    textField.text = pickerData[row]
   else textField2.text = pickerData2[row]

【讨论】:

【参考方案6】:

您可以简单地检查哪个文本字段处于编辑状态。在您完成的单击功能中执行此操作。您不必向 pickerView 或 textField 添加任何标签。

 func pickerDoneAction(sender: UIBarButtonItem) 
    if textField1.isEditing == true 
        Print("pickerview 1 is selected")
     else 
        Print("pickerview 2 is selected")
    

希望这会有所帮助! :)

【讨论】:

以上是关于确定哪个 UIPicker 的工具栏按钮发送了消息的主要内容,如果未能解决你的问题,请参考以下文章

Symfony Messenger 如何确定应由哪个处理程序处理每种类型的消息?

确定用户按下了哪个按钮

确定在使用按钮数组时单击了哪个提交按钮

使用工具栏按钮更改 UIPickerView 值

发送自发的短暂不和谐消息

确定使用了哪个提交按钮?