确定哪个 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】:
您始终可以使用UIView
的tag
属性传递数据:
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 的工具栏按钮发送了消息的主要内容,如果未能解决你的问题,请参考以下文章