Swift 4中Alert的UITextField最大长度

4

如何在Alert中设置UITextField的最大长度?

在Swift 4中,最佳实践是什么?

这是我的代码示例,但它会因为UITextField在开头不存在而崩溃。

class ViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var textField: UITextField!
let limitLength = 10
@IBOutlet weak var player1: UIButton!


func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    guard let text = textField.text else { return true }
    let newLength = text.characters.count + string.characters.count - range.length
    return newLength <= limitLength
}

@IBAction func player1Action(_ sender: UIButton) {
    let alertController = UIAlertController(title: "Please enter you name", message: "Maximum 10 characters", preferredStyle: .alert)
    alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: {
        alert -> Void in
        let textField = alertController.textFields![0] as UITextField
        // do something with textField
        self.player1.setTitle("\(textField.text!)", for: .normal)
    }))
    alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))

    alertController.addTextField(configurationHandler: {(textField : UITextField!) -> Void in
        textField.placeholder = "Name"
    })
    self.present(alertController, animated: true, completion: nil)

}


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    textField.delegate = self

}

非常感谢你的时间。
3个回答

10

实际上,您不需要创建一个UITextField的实例。 addTextField闭包将为您返回UITextField。您所需要做的就是在闭包中设置该文本字段的委托。

class ViewController: UIViewController, UITextFieldDelegate {
    let limitLength = 10
    @IBOutlet weak var player1: UIButton!

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        guard let text = textField.text else { return true }
        let newLength = text.characters.count + string.characters.count - range.length
        return newLength <= limitLength
    }

    @IBAction func player1Action(_ sender: UIButton) {
        let alertController = UIAlertController(title: "Please enter you name", message: "Maximum 10 characters", preferredStyle: .alert)
        alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: {
            alert -> Void in
            let textField = alertController.textFields![0] as UITextField
            self.player1.setTitle("\(textField.text!)", for: .normal)
        }))
        alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))

        alertController.addTextField(configurationHandler: {(textField : UITextField!) -> Void in
            textField.placeholder = "Name"
            textField.delegate = self // Set the delegate
        })

        present(alertController, animated: true, completion: nil)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

1
class MaxLengthTextField: UITextField, UITextFieldDelegate {

    private var characterLimit: Int?

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        delegate = self
    }

    @IBInspectable var maxLength: Int {
        get {
            guard let length = characterLimit else {
                return Int.max
            }
            return length
        }
        set {
            characterLimit = newValue
        }
    }

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

        guard string.characters.count > 0 else {
            return true
        }

        let currentText = textField.text ?? ""
        let prospectiveText = (currentText as NSString).replacingCharacters(in: range, with: string)

        // 1. Here's the first change...
        return allowedIntoTextField(text: prospectiveText)
    }

    // 2. ...and here's the second!
    func allowedIntoTextField(text: String) -> Bool {
        return text.characters.count <= maxLength
    }
}

您可以将此类用于多个文本字段。只需将MaxLengthTextField类添加到任何文本字段中。然后,您可以从Storyboard中修改文本字段中的字符数。附注:这是Swift 3.0。


好的,您可以将此类用于多个文本字段。只需将MaxLengthTextField类添加到任何文本字段中即可。然后,您可以从Storyboard中修改文本字段中的字符数。附:这是Swift 3.0。 - tBug
谢谢。你能编辑一下答案吗?这样对于阅读的人会很有帮助。我会点赞的。 - Tom M
不需要点赞,我这样做是为了帮助他人。我不在意技能栏等级。谢谢。 - tBug

0

你可以使用一些 Rx 函数来处理它,就像这样

let doneAction = UIAlertAction(title: NSLocalizedString("OK", comment: ""), style: .default, handler: { _ in
        block?(alert.textFields?.first?.text)
    })
    alert.addAction(doneAction)
    alert.addTextField { textField in
        textField.autocapitalizationType = .sentences
        textField.placeholder = NSLocalizedString("Placeholder", comment: "")
        textField.rx.text.orEmpty.map {
            if $0.hasPrefix(" ") {
                textField.text = $0.trimmingCharacters(in: .whitespaces)
                return false
            }
            return $0.count > 0 && $0.count < 30
        }.share(replay: 1).bind(to: doneAction.rx.isEnabled).disposed(by: self.disposeBag)
    }

这里我正在使用 Rx 将文本字段与警告的“确定”按钮连接起来,如果文本以空格开头、长度为 0 或最大长度为 30,则禁用该按钮。别忘了初始化 disposeBag,它必须是全局的。

private var disposeBag: DisposeBag = DisposeBag()

并且导入

import RxSwift
import RxCocoa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接