繁体   English   中英

防止在 Swift 中编辑 UITextField 而不是用户交互

[英]Prevent editing UITextField but not the user interaction in Swift

我想知道如何防止用户编辑 UITextField 而不是用户交互。 我想在这里做的是当用户点击文本字段时,UIPickerView 从底部弹出,用户可以从选择器视图中选择一个项目并将其显示在文本字段上。 但我不希望用户能够编辑文本字段。 我想为下面的班级做到这一点。

import UIKit

typealias PickerTextFieldDisplayNameHandler = ((Any) -> String)
typealias PickerTextFieldItemSelectionHandler = ((Int, Any) -> Void)

class PickerTextField: UITextField {

    private let pickerView = UIPickerView(frame: .zero)
    private var lastSelectedRow: Int?
    
    public var pickerData: [Any] = []
    public var displayNameHandler: PickerTextFieldDisplayNameHandler?
    public var itemSelectionHandler: PickerTextFieldItemSelectionHandler?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.configureView()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        self.configureView()
    }
    
    override func caretRect(for position: UITextPosition) -> CGRect {
        return .zero
    }
    
    
    
    private func configureView() {
        self.pickerView.delegate = self
        self.pickerView.dataSource = self
        self.inputView = pickerView
        
        let toolbar = UIToolbar()
        toolbar.barStyle = .default
        toolbar.sizeToFit()
        
        let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
        let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(doneButtonTapped))
        toolbar.setItems([spaceButton, doneButton], animated: false)
        
        self.inputAccessoryView = toolbar
    }
    
    private func updateText() {
        if self.lastSelectedRow == nil {
            self.lastSelectedRow = 0
        }
        if self.lastSelectedRow! > self.pickerData.count {
            return
        }
        let data = self.pickerData[self.lastSelectedRow!]
        self.text = self.displayNameHandler?(data)
    }
    
    @objc func doneButtonTapped() {
        self.updateText()
        self.resignFirstResponder()
    }
    
}

extension PickerTextField: UIPickerViewDelegate {
    
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        let data = self.pickerData[row]
        return self.displayNameHandler?(data)
    }
}

extension PickerTextField: UIPickerViewDataSource {
    
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return self.pickerData.count
    }
    
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        self.lastSelectedRow = row
        self.updateText()
        let data = self.pickerData[row]
        self.itemSelectionHandler?(row, data)
    }
}

据我了解,您希望实现以下行为:

  1. 您想显示用户在文本字段内的选择器视图中选择的内容。
  2. 但是您不希望用户在文本字段中插入文本后更改文本。

我会使用UITextFieldUIPickerView的委托方法。 UIPickerViewDelegate中有一个方法可以让您知道用户选择了哪一行:

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    textField.text = "Hello \(row)"
}

在这里,您可以将文本设置为解决 (1) 的文本字段。

您还可以使用UITextFieldDelegate中的方法来阻止用户输入文本字段。

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    return false
}

这可以防止用户在文本字段中输入任何内容。 这解决了(2)。 但是,光标仍会显示,这可能会使用户感到困惑。 他可能认为他可以通过闪烁的光标在文本字段中输入内容,而实际上他不能。

当然,您必须将 textfield 的inputView设置为您的自定义选择器视图,如下所示:

textField.inputView = myPickerView

我希望这回答了你的问题 :)

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM