【问题标题】:Prevent editing UITextField but not the user interaction in Swift防止编辑 UITextField 但不是 Swift 中的用户交互
【发布时间】:2021-12-19 13:01:20
【问题描述】:

我想知道如何防止用户编辑 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)
    }
}

【问题讨论】:

  • 不可编辑的文本字段将是 UILabel。 :) 事实上,你可以点击一个标签来显示一个填充标签的选择器是很常见的事情。

标签: ios swift uitextfield


【解决方案1】:

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

  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)。但是,光标仍会显示,这可能会使用户感到困惑。他可能认为他可以通过光标闪烁在文本字段中输入内容,而实际上他不能。

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

textField.inputView = myPickerView

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 2013-12-20
    • 2018-06-01
    相关资源
    最近更新 更多