如何向 UIPickerView 添加按钮?
How do you add a button to a UIPickerView?
如何向 UIPickerView 添加一个可用于关闭或隐藏 PickerView 的按钮?
我找到了一些解决这些问题的方法,但很多似乎都没有得到我想要的答案。 This 问题是我能找到的最接近我要问的问题,但它已经过时了,所以我想展示我的解决方案。我有一个 UIPickerView 的子类,我想添加一个 UIButton 以便能够关闭。我不想要一个里面有 UIToolBar 的 UIPickerView。
下图准确地描述了我正在寻找的完成按钮添加到我的 UIPickerView 子类的地方
您需要做的就是向 UIPickerView 添加一个 UIButton 并添加一个目标以调用方法,这似乎微不足道,因为我还希望 PickerView 响应用户在行上的选择,按下 Done按钮没有反应
创建 UIView 的子类
class CustomViewWithPicker: UIView {
let picker = UIPickerView(frame: .zero)
let pickerTitle = UILabel(frame: .zero)
let button = UIButton(frame: .zero)
let title: String = "Picker Title"
let buttonName: String = "Button"
override init(frame: CGRect) {
super.init(frame: frame)
didLoad()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
didLoad()
}
func didLoad() {
self.addSubview(picker)
self.addSubview(pickerTitle)
self.addSubview(button)
picker.backgroundColor = .tertiarySystemBackground
picker.layer.cornerRadius = 20
picker.frame = .zero
pickerTitle.text = title
pickerTitle.font = .boldSystemFont(ofSize: 22)
pickerTitle.textAlignment = .center
pickerTitle.backgroundColor = .tertiarySystemBackground
button.setTitle(buttonName, for: .normal)
button.contentHorizontalAlignment = .right
button.contentVerticalAlignment = .top
button.isSelected = true
self.updateConstraints()
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if self.point(inside: point, with: event) {
return super.hitTest(point, with: event)
}
guard isUserInteractionEnabled, !isHidden, alpha > 0 else {
return nil
}
for subview in subviews.reversed() {
let convertedPoint = subview.convert(point, from: self)
if let hitView = subview.hitTest(convertedPoint, with: event) {
return hitView
}
}
return nil
}
override func layoutSubviews() {
super.layoutSubviews()
}
override func updateConstraints() {
// Make Constraints ...
}
}
在ViewController符合UIPickerViewDelegate和UIPickerViewDataSource
class MyViewController : UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UIGestureRecognizerDelegate {
let customView = CustomViewWithPicker()
let labels = ["label0", "label1", "label2", "label3", "label4", "label5"]
var selectedRow = 0
override func viewDidLoad() {
super.viewDidLoad()
customView.picker.delegate = self
customView.picker.dataSource = self
customView.button.addTarget(self, action: #selector(doneButtonTapped(_:)), for: .touchUpInside)
self.view.addSubview(customView)
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return labels.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return labels[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
selectedRow = row
}
@objc func doneButtonTapped(_ selectedButton: UIButton) {
if selectedButton.isSelected {
print("Done Button Tapped")
}
}
}
我四处寻找不依赖 UIToolBar 检测按钮点击的 UIPickerView 实现,但无济于事。
感谢 Duncan C. 的意见和建议
简答:不要那样做。
Apple 表示不要弄乱其组件的视图层次结构。您应该创建一个包含选择器和按钮的组件,并使它们看起来像一个单一的多部分组件。这样,如果 Apple 在未来的版本中更改 UIPickerView 的内部结构,它不会破坏你。
如何向 UIPickerView 添加一个可用于关闭或隐藏 PickerView 的按钮?
我找到了一些解决这些问题的方法,但很多似乎都没有得到我想要的答案。 This 问题是我能找到的最接近我要问的问题,但它已经过时了,所以我想展示我的解决方案。我有一个 UIPickerView 的子类,我想添加一个 UIButton 以便能够关闭。我不想要一个里面有 UIToolBar 的 UIPickerView。
下图准确地描述了我正在寻找的完成按钮添加到我的 UIPickerView 子类的地方
您需要做的就是向 UIPickerView 添加一个 UIButton 并添加一个目标以调用方法,这似乎微不足道,因为我还希望 PickerView 响应用户在行上的选择,按下 Done按钮没有反应
创建 UIView 的子类
class CustomViewWithPicker: UIView {
let picker = UIPickerView(frame: .zero)
let pickerTitle = UILabel(frame: .zero)
let button = UIButton(frame: .zero)
let title: String = "Picker Title"
let buttonName: String = "Button"
override init(frame: CGRect) {
super.init(frame: frame)
didLoad()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
didLoad()
}
func didLoad() {
self.addSubview(picker)
self.addSubview(pickerTitle)
self.addSubview(button)
picker.backgroundColor = .tertiarySystemBackground
picker.layer.cornerRadius = 20
picker.frame = .zero
pickerTitle.text = title
pickerTitle.font = .boldSystemFont(ofSize: 22)
pickerTitle.textAlignment = .center
pickerTitle.backgroundColor = .tertiarySystemBackground
button.setTitle(buttonName, for: .normal)
button.contentHorizontalAlignment = .right
button.contentVerticalAlignment = .top
button.isSelected = true
self.updateConstraints()
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if self.point(inside: point, with: event) {
return super.hitTest(point, with: event)
}
guard isUserInteractionEnabled, !isHidden, alpha > 0 else {
return nil
}
for subview in subviews.reversed() {
let convertedPoint = subview.convert(point, from: self)
if let hitView = subview.hitTest(convertedPoint, with: event) {
return hitView
}
}
return nil
}
override func layoutSubviews() {
super.layoutSubviews()
}
override func updateConstraints() {
// Make Constraints ...
}
}
在ViewController符合UIPickerViewDelegate和UIPickerViewDataSource
class MyViewController : UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UIGestureRecognizerDelegate {
let customView = CustomViewWithPicker()
let labels = ["label0", "label1", "label2", "label3", "label4", "label5"]
var selectedRow = 0
override func viewDidLoad() {
super.viewDidLoad()
customView.picker.delegate = self
customView.picker.dataSource = self
customView.button.addTarget(self, action: #selector(doneButtonTapped(_:)), for: .touchUpInside)
self.view.addSubview(customView)
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return labels.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return labels[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
selectedRow = row
}
@objc func doneButtonTapped(_ selectedButton: UIButton) {
if selectedButton.isSelected {
print("Done Button Tapped")
}
}
}
我四处寻找不依赖 UIToolBar 检测按钮点击的 UIPickerView 实现,但无济于事。
感谢 Duncan C. 的意见和建议
简答:不要那样做。
Apple 表示不要弄乱其组件的视图层次结构。您应该创建一个包含选择器和按钮的组件,并使它们看起来像一个单一的多部分组件。这样,如果 Apple 在未来的版本中更改 UIPickerView 的内部结构,它不会破坏你。