Mac Catalyst 下是不是支持 UITextField+UIPickerView?
Posted
技术标签:
【中文标题】Mac Catalyst 下是不是支持 UITextField+UIPickerView?【英文标题】:Is UITextField+UIPickerView supported under Mac Catalyst?Mac Catalyst 下是否支持 UITextField+UIPickerView? 【发布时间】:2020-05-23 22:28:50 【问题描述】:在我的 ios 应用程序中,我有一个文本字段,其中有一个分配给它的 inputView 的选取器视图。在 iOS 设备上,每当用户点击文本字段时,选择器视图就会弹出。但是,当我将它作为 Mac/Catalyst 应用程序运行时,相同的代码不会这样做。到目前为止,我的调试工作表明,选择器视图方法根本没有被调用,所以如果 Mac 需要额外的文本字段委托方法来将焦点从 Mac 的键盘上移开?知道如何在 Mac 上进行这项工作吗?下面是一个准系统示例代码。
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate
@IBOutlet weak var myTextField: UITextField!
var myPickerView : UIPickerView!
var pickerData = ["Alpha" , "Bravo" , "Charlie" , "Delta"]
override func viewDidLoad()
super.viewDidLoad()
self.myPickerView = UIPickerView(frame:CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 300))
self.myPickerView.delegate = self
self.myPickerView.dataSource = self
self.myTextField.delegate = self
self.myTextField.inputView = self.myPickerView
func numberOfComponents(in pickerView: UIPickerView) -> Int
return 1
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int
return pickerData.count
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String?
return pickerData[row]
【问题讨论】:
你有没有得到这个工作? 【参考方案1】:它看起来像 Mac Catalyst 中的一个错误。尝试使用嵌入在UIActionSheet
中的UIPicker
。 ActionSheetPicker-3.0 是现成的解决方案。在您的UITextField
的textFieldDidBeginEditing
中显示ActionSheetPicker
。
【讨论】:
【参考方案2】:这有点小技巧,但还是让我分享一下。如果您收听 NSNotification UIKeyboardWillChangeFrameNotification
这将在-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
之前触发
所以你可以设置一个 BOOL 来查看这个方法是否触发。如果没有,您可以判断您没有软件键盘,然后可以显示警报控制器或上下文菜单,或者您想以不同的方式处理它。
【讨论】:
【参考方案3】:视图控制器
class ViewController : UIViewController
// MARK: - Properties -
var tableView : UITableView?
var currentTextfield : UITextField?
var gendersArray : Array<String> = ["Male", "Female"]
var pickerView : UIPickerView?
// MARK: - Lifecycle -
override func viewDidLoad()
super.viewDidLoad()
// get the size of the iOS device
let screenRect : CGRect = UIScreen.main.bounds
let screenWidth : CGFloat = screenRect.size.width
let screenHeight : CGFloat = screenRect.size.height
// add the picker view
var pickerViewFrame = CGRect(x: 0.0,
y: screenHeight - 162.0,
width: screenWidth,
height: 162.0)
// set pickerview frame for macOS Catalyst
#if targetEnvironment(macCatalyst)
pickerViewFrame = CGRect(x: 0, y: 0, width: 269, height: 240)
#endif
pickerView = UIPickerView.init(frame: pickerViewFrame)
pickerView?.delegate = self
pickerView?.dataSource = self
// ... set tableview
UIAlertController 函数
// MARK: - UIAlertController -
@objc func textfieldInputAction(pickerView: UIPickerView, textfield: UITextField?)
print("textfieldInputAction")
// alertController
let alertController = UIAlertController(title: "Title of Action Sheet", message: "", preferredStyle: UIAlertController.Style.actionSheet)
// reload components
pickerView.reloadAllComponents()
// add the picker to the alert controller
alertController.view.addSubview(pickerView)
// set height of Action sheet
let height : NSLayoutConstraint = NSLayoutConstraint(item: alertController.view!, attribute: NSLayoutConstraint.Attribute.height, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: 350)
alertController.view.addConstraint(height)
// okAction
let okAction = UIAlertAction(title: "Done", style: .default, handler:
(alert: UIAlertAction!) -> Void in
// end editing
DispatchQueue.main.async
textfield?.resignFirstResponder()
DispatchQueue.main.async
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
)
alertController.addAction(okAction)
// popoverController
if let popoverController = alertController.popoverPresentationController
popoverController.sourceView = textfield //to set the source of your alert
popoverController.sourceRect = textfield?.bounds ?? CGRect(x: 0, y: 0, width: 0, height: 0 )
popoverController.permittedArrowDirections = [.down, .up]
// present alertController
self.present(alertController, animated: true, completion: nil)
表格视图
// MARK: - Tableview -
extension ViewController : UITableViewDelegate, UITableViewDataSource
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell : TextFieldCell = tableView.dequeueReusableCell(withIdentifier: "TextFieldCell", for: indexPath) as! TextFieldCell
// textfield
cell.textField?.delegate = self
cell.textField?.inputView = pickerView
return cell
UITextField 委托
// MARK: - UITextField -
extension ViewController : UITextFieldDelegate
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool
print("textFieldShouldBeginEditing")
#if targetEnvironment(macCatalyst)
if textField.inputView == self.pickerView
self.currentTextfield = textField
self.textfieldInputAction(pickerView: self.pickerView!, textfield: self.currentTextfield!)
return false
#endif
return true
UIPickerView 委托
// MARK: - PickerView Delegates -
extension ViewController : UIPickerViewDelegate, UIPickerViewDataSource
// components
func numberOfComponents(in pickerView: UIPickerView) -> Int
return 1
// rows
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int
print("numberOfRowsInComponent")
return gendersArray.count
// title
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String?
return gendersArray[row]
// select row
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
print("pickerView: didSelectRow: \(row)")
currentTextfield?.text = gendersArray[row]
self.tableView?.reloadData()
【讨论】:
【参考方案4】:在 UIPickerViewMioPicker.swift 上
class UIPickerViewMio : NSObject, UIPickerViewDataSource, UIPickerViewDelegate
private var uiTextField : UITextField?
private var oggetto = ["Uno", "Due", "Tre", "Quattro", "Cinque"]
required init(uiTextField : UITextField?)
self.uiTextField = uiTextField
func numberOfComponents(in pickerView: UIPickerView) -> Int
return 1
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int
return 5
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
if let textField = self.uiTextField
textField.text = self.oggetto[row]
textField.tag = row
... omissis ...
在 UIViewController 上
@IBOutlet var textMioText : UITextField?
var uiPickerViewMioPicker : UIPickerViewMioPicker?
override func viewDidLoad()
... omissis ...
self.uiPickerViewMio = UIPickerViewMioPicker(uiTextField: self.textMioText)
let pickerM = UIPickerView()
pickerM.delegate = self.uiPickerViewMioPicker
pickerM.dataSource = self.uiPickerViewMioPicker
self.textMioText?.inputView = pickerM
... omissis ...
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool
if textField == self.textMio
let picker = textField.inputView as! UIPickerView
picker.isHidden = false
if UIDevice.current.systemName == "Mac OS X"
let alertPicker = UIAlertController(title: "", message: "", preferredStyle: UIAlertController.Style.actionSheet)
alertPicker.view.addSubview(picker)
alertPicker.view.addConstraint(NSLayoutConstraint(item: alertPicker.view!, attribute: NSLayoutConstraint.Attribute.height, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: picker.bounds.height * 1.1))
alertPicker.view.addConstraint(NSLayoutConstraint(item: alertPicker.view!, attribute: NSLayoutConstraint.Attribute.width, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: picker.bounds.width * 1.1))
if let popoverController = alertPicker.popoverPresentationController
popoverController.sourceView = textField
popoverController.sourceRect = textField.bounds
popoverController.permittedArrowDirections = [.down, .up]
self.present(alertPicker, animated: true, completion: nil)
return false
return true
【讨论】:
以上是关于Mac Catalyst 下是不是支持 UITextField+UIPickerView?的主要内容,如果未能解决你的问题,请参考以下文章
关于Cisco Catalyst 2960-S Series SI 交换机支持IP和MAC地址绑定功能吗?
如何修复“读写数据沙箱:使用 Mac Catalyst 时出错”
关于Cisco Catalyst 2960-S Series SI 交换机支持IP和MAC地址绑定功能吗?
Mac Catalyst ITMS-4241 错误上传二进制文件