【问题标题】: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]
}
}

【问题讨论】:

  • 你有没有得到这个工作?

标签: uitextfield uipickerview mac-catalyst


【解决方案1】:

它看起来像 Mac Catalyst 中的一个错误。尝试使用嵌入在UIActionSheet 中的UIPickerActionSheetPicker-3.0 是现成的解决方案。在您的UITextFieldtextFieldDidBeginEditing 中显示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}
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-05-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-12-06
          相关资源
          最近更新 更多