如何为UITextField占位符字符添加间距?
Hey there! Let's sort out that placeholder character spacing issue you're tackling. Your initial code was applying kerning to the text users enter, not the placeholder itself—that's why it wasn't giving you the result you wanted. Let's break down the correct approaches:
The simplest way is to create an attributed string with your desired character spacing (kerning) and assign it directly to the text field's attributedPlaceholder property. This works great if you know the placeholder text upfront.
func setTextFieldPlaceholderCharacterSpacing(txtField: UITextField, placeholderText: String) { // Define your placeholder styles: kerning + any extras like color let placeholderAttributes: [NSAttributedString.Key: Any] = [ .kern: CGFloat(8.0), .foregroundColor: UIColor.lightGray ] let attributedPlaceholder = NSAttributedString( string: placeholderText, attributes: placeholderAttributes ) txtField.attributedPlaceholder = attributedPlaceholder }
If you need this spacing behavior across multiple text fields in your app, subclassing UITextField lets you encapsulate the logic so you don't repeat code everywhere.
class SpacedPlaceholderTextField: UITextField { // Define a custom property to adjust kerning easily var placeholderKerning: CGFloat = 8.0 { didSet { updateAttributedPlaceholder() } } // Update the attributed placeholder whenever the base placeholder text changes override var placeholder: String? { didSet { updateAttributedPlaceholder() } } private func updateAttributedPlaceholder() { guard let placeholderText = placeholder else { return } let attributes: [NSAttributedString.Key: Any] = [ .kern: placeholderKerning, .foregroundColor: self.placeholderColor ?? UIColor.lightGray ] self.attributedPlaceholder = NSAttributedString( string: placeholderText, attributes: attributes ) } // Optional: Keep spacing consistent if placeholder color is updated via other methods override func setValue(_ value: Any?, forKey key: String) { super.setValue(value, forKey: key) if key == "_placeholderLabel.textColor" { updateAttributedPlaceholder() } } }
Why Your Initial Code Didn't Work
Your original function modified txtField.attributedText, which affects the text the user has typed into the field—not the placeholder that shows when the field is empty. The placeholder is a separate element, controlled by the attributedPlaceholder property, which needs its own attributed string with the kerning attribute.
Delegate-Based Approach (If You Need It)
If you specifically want to handle placeholder spacing via the UITextFieldDelegate (like adjusting spacing when the user starts/ends editing), you can update the attributedPlaceholder in the relevant delegate methods:
extension LoginVC: UITextFieldDelegate { func textFieldDidBeginEditing(_ textField: UITextField) { // Adjust placeholder kerning when editing starts let editingAttributes: [NSAttributedString.Key: Any] = [ .kern: CGFloat(6.0), .foregroundColor: UIColor.gray ] textField.attributedPlaceholder = NSAttributedString( string: textField.placeholder ?? "", attributes: editingAttributes ) } func textFieldDidEndEditing(_ textField: UITextField) { // Reset to original kerning when editing ends let defaultAttributes: [NSAttributedString.Key: Any] = [ .kern: CGFloat(8.0), .foregroundColor: UIColor.lightGray ] textField.attributedPlaceholder = NSAttributedString( string: textField.placeholder ?? "", attributes: defaultAttributes ) } }
内容的提问来源于stack exchange,提问作者Kuldeep

