如何实现占位符文本在UITextField中逐个字符消失

时间:2017-09-05 06:50:59

标签: ios objective-c xcode uitextfield placeholder

你能帮我吗?

在我们提供占位符文本的UITextField中,当我们输入任何字符时,其占位符字符串将会消失。我怎样才能实现只输入的字符不会是完整的字符串?这意味着如果我输入3个字符,只占位符的前3个字符就会消失。

enter image description here

#EDIT 1

此外,新输入的字符文本颜色将更改,其他剩余字符文本颜色保持不变。

提前致谢。

6 个答案:

答案 0 :(得分:4)

不使用占位符文本,而是在文本字段下方使用UILabel,并为两者提供相同的字体样式。标签文本应该是 比如“ - - - - - ”

当用户开始在文本字段上键入时,在每个字符按下后给出一个空格。

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

    if textField.text?.characters.count == 0 && string.characters.count != 0 {
        textField.text = textField.text! + " "
    }
     else {
        return false
    }

    if textField.text?.characters.count == 1 && string.characters.count != 0 {
        textField.text = textField.text! + " "
    }
    else {
        return false
    }

    if textField.text?.characters.count == 2 && string.characters.count != 0 {
        textField.text = textField.text! + " "
    }
    else {
        return false
    }
    if textField.text?.characters.count == 3 && string.characters.count != 0 {
        textField.text = textField.text! + " "
    }
    else {
        return false
    }

    return true
}

答案 1 :(得分:4)

我不相信占位符的默认行为是可编辑的,但您尝试完成的操作可以使用NSAttributedString来模拟占位符值。

我确信这可以优化,但在这里我创建了一个处理程序类,它充当给定UITextField的委托,操纵用户输入的字符串以实现所需的效果。使用所需的占位符字符串初始化处理程序,这样就可以使任何文本字段以这种方式工作。

Custom Placeholder Text Field

import UIKit

class CustomPlaceholderTextFieldHandler: NSObject {
    let placeholderText: String
    let placeholderAttributes = [NSForegroundColorAttributeName : UIColor.lightGray]
    let inputAttributes = [NSForegroundColorAttributeName : UIColor(red: 255/255, green: 153/255, blue: 0, alpha: 1.0)]
    var input = ""

    init(placeholder: String) {
        self.placeholderText = placeholder
        super.init()
    }

    func resetPlaceholder(for textField: UITextField) {
        input = ""
        setCombinedText(for: textField)
    }

    fileprivate func setCursorPosition(for textField: UITextField) {
        guard let cursorPosition = textField.position(from: textField.beginningOfDocument, offset: input.characters.count)
            else { return }

        textField.selectedTextRange = textField.textRange(from: cursorPosition, to: cursorPosition)
    }

    fileprivate func setCombinedText(for textField: UITextField) {
        let placeholderSubstring = placeholderText.substring(from: input.endIndex)
        let attributedString = NSMutableAttributedString(string: input + placeholderSubstring, attributes: placeholderAttributes)
        attributedString.addAttributes(inputAttributes, range: NSMakeRange(0, input.characters.count))
        textField.attributedText = attributedString
    }
}

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

        if string == "" {
            if input.characters.count > 0 {
                input = input.substring(to: input.index(before: input.endIndex))
            }
        } else {
            input += string
        }

        if input.characters.count <= placeholderText.characters.count {
            setCombinedText(for: textField)
            setCursorPosition(for: textField)
            return false
        }
        return true
    }

    func textFieldDidBeginEditing(_ textField: UITextField) {
        setCursorPosition(for: textField)
    }
}

这是我初始化上面的gif的方式:

class ViewController: UIViewController {

    @IBOutlet weak var textField: UITextField!
    let placeholderHandler = CustomPlaceholderTextFieldHandler(placeholder: "_2_-__-__A")

    override func viewDidLoad() {
        super.viewDidLoad()
        textField.delegate = placeholderHandler
        placeholderHandler.resetPlaceholder(for: textField)
    }
}

这可以扩展为在初始化时获取颜色参数,字体等,或者您可能会发现它更加清晰,可以将UITextField子类化为自己的委托。我还没有通过选择/删除/替换多个字符来测试它。

input变量将返回用户在任何给定点输入的文本。此外,使用固定宽度字体可以消除用户键入和替换占位符文本时的抖动。

答案 2 :(得分:2)

我的解决方案使用UITextField文本属性

else
  • 最初将文本字段文本设置为屏蔽模板
  • 然后当用户输入输入时调用了shouldChangeCharactersInRange并且它做得很好

#Edit 1 还有一些我已经实现的代码将光标移动到下划线位置。如果有人需要帮助。请评论我会帮助你。

#Edit 2

使用此方法遇到的问题

  • 无法更改单个文字颜色。对于像@&#34; _&#34;这样的字符串,颜色将是相同的。下划线和输入字符具有相同的颜色。
  • 如果用户没有提供任何输入,那么我必须提供检查以将空白作为字符串发送。
  • 跟踪个人输入。

谢谢, 仍然在等待使用占位符字符串的任何其他解决方法。

答案 3 :(得分:1)

我想这正是你要找的。使用文本UITextField创建_2_-__-__A对象(不是占位符文本)。然后,将其视图控制器用作委托,并将其添加到视图控制器:

-(BOOL)textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)string{
    if (range.length>1) return NO; // Avoids removing multiple characters at once
    if (range.location==1) range.location++;  // '2' index
    if (range.location==3) range.location++;  // '-' index
    if (range.location==6) range.location++;  // '-' index
    if (range.location==9)  return NO; // 'A' index
    if (range.location==10) return NO; // String end
    if ([string isEqualToString:@""]) return NO; //Avoids removing characters

    if (range.length==0) {
        range.length++;
        UITextPosition *beginning = textField.beginningOfDocument;
        UITextPosition *start = [textField positionFromPosition:beginning offset:range.location];
        UITextPosition *end = [textField positionFromPosition:start offset:range.length];
        UITextRange *textRange = [textField textRangeFromPosition:start toPosition:end];
        [textField setSelectedTextRange:textRange];
    }

    return YES;
}
-(void)textFieldDidBeginEditing:(UITextField*)textField{
    UITextPosition *beginning = textField.beginningOfDocument;
    UITextPosition *start = [textField positionFromPosition:beginning offset:0];
    UITextPosition *end = [textField positionFromPosition:start offset:0];
    UITextRange *textRange = [textField textRangeFromPosition:start toPosition:end];
    [textField setSelectedTextRange:textRange];
}
-(BOOL)textFieldShouldReturn:(UITextField*)textField{
    [passwordInput resignFirstResponder];
    return YES;
}

它应该按预期工作。

答案 4 :(得分:-1)

对于那种情况,请使用swift中的字符串,如下所述,

let attributeFontSaySomething : [String : Any] = [NSFontAttributeName : UIFont.systemFont(ofSize: 12.0)]
let attributeColorSaySomething : [String : Any] = [NSForegroundColorAttributeName : UIColor.blue]

var attributes = attributeFontSaySomething
for (key, value) in attributeColorSaySomething {
    attributes(value, forKey: key)
}

let attStringSaySomething = NSAttributedString(string: "Say something", attributes: attributes)

答案 5 :(得分:-3)

否如果没有在UITextfield上创建自定义图层之后你不能这样做,你需要检查输入的char是否与placehoder字符串匹配,然后只更换那个字符。 另见Replacing character after each type in UITextField?