You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在UITextField的else分支中恢复原始placeholder值?

如何恢复UITextField的原始Placeholder值?

你的问题出在每次调用fieldEmptyError函数时,才临时获取当前的placeholder值作为textFieldVal——当第一次触发if分支修改了placeholder后,后续调用函数时,textField.placeholder已经变成了带*的版本,自然无法恢复原始值。

要解决这个问题,核心是提前持久保存每个UITextField的原始placeholder值,而不是每次调用函数时临时获取。下面是两种实用的解决方案:

方案一:给UITextField添加关联对象(推荐,通用型)

这种方式可以给每个UITextField绑定一个原始placeholder的存储属性,不管你有多少个输入框都能复用,非常灵活:

首先创建UITextField的扩展,通过关联对象存储原始值:

import UIKit

// 关联对象的唯一标识key
private var originalPlaceholderKey: UInt8 = 0

extension UITextField {
    // 自定义属性,用于存储原始placeholder
    var originalPlaceholder: String? {
        get {
            return objc_getAssociatedObject(self, &originalPlaceholderKey) as? String
        }
        set {
            objc_setAssociatedObject(self, &originalPlaceholderKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
}

然后修改你的fieldEmptyError函数,第一次调用时保存原始placeholder,之后始终用这个保存的值来恢复:

func fieldEmptyError(value: Bool, textField: UITextField) {
    // 首次调用时,把当前的placeholder(也就是原始值)保存起来
    if textField.originalPlaceholder == nil {
        textField.originalPlaceholder = textField.placeholder
    }
    
    // 确保能拿到原始值,避免崩溃
    guard let originalPlaceholder = textField.originalPlaceholder else { return }
    
    if value {
        layer.borderColor = UIColor.red.cgColor
        layer.cornerRadius = 5.0
        layer.masksToBounds = true
        layer.borderWidth = 1
        pulsate()
        // 使用原始值拼接错误提示
        textField.attributedPlaceholder = NSAttributedString(
            string: "\(originalPlaceholder) required *",
            attributes: [
                .foregroundColor: UIColor.red,
                .font: UIFont.systemFont(ofSize: 17.0)
            ]
        )
    } else {
        layer.borderColor = UIColor.black.cgColor
        // 直接使用保存的原始值恢复placeholder
        textField.attributedPlaceholder = NSAttributedString(
            string: originalPlaceholder,
            attributes: [
                .foregroundColor: UIColor.black,
                .font: UIFont.systemFont(ofSize: 17.0)
            ]
        )
    }
}

方案二:外部存储原始值(适合单个输入框场景)

如果你的页面只有少数几个输入框,也可以在ViewController中直接声明属性存储原始placeholder:

// 在ViewController里定义原始值
let originalUsernamePlaceholder = "Username"
let originalPasswordPlaceholder = "Password"

// 修改函数,直接用预定义的原始值
func fieldEmptyError(value: Bool, textField: UITextField) {
    var originalPlaceholder: String
    // 根据textField判断用哪个原始值
    if textField == usernameTextField {
        originalPlaceholder = originalUsernamePlaceholder
    } else if textField == passwordTextField {
        originalPlaceholder = originalPasswordPlaceholder
    } else {
        originalPlaceholder = textField.placeholder ?? ""
    }
    
    // 后续逻辑和之前一致,只是用originalPlaceholder代替textFieldVal
    if value {
        layer.borderColor = UIColor.red.cgColor
        layer.cornerRadius = 5.0
        layer.masksToBounds = true
        layer.borderWidth = 1
        pulsate()
        textField.attributedPlaceholder = NSAttributedString(
            string: "\(originalPlaceholder) required *",
            attributes: [
                .foregroundColor: UIColor.red,
                .font: UIFont.systemFont(ofSize: 17.0)
            ]
        )
    } else {
        layer.borderColor = UIColor.black.cgColor
        textField.attributedPlaceholder = NSAttributedString(
            string: originalPlaceholder,
            attributes: [
                .foregroundColor: UIColor.black,
                .font: UIFont.systemFont(ofSize: 17.0)
            ]
        )
    }
}

这样不管你多少次触发if或else分支,都能准确获取到最初的placeholder值,实现你想要的恢复效果。

内容的提问来源于stack exchange,提问作者Abhinav Jha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:16:48