代码之家  ›  专栏  ›  技术社区  ›  iamVishal16

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

  •  20
  • iamVishal16  · 技术社区  · 7 年前

    你能帮帮我吗。

    UITextField 当我们提供占位符文本时,当我们输入任何字符时,其占位符字符串将消失。我如何才能做到只有输入的字符将消失,而不是一个完整的字符串?也就是说,如果我输入3个字符,占位符的前3个字符就会消失。

    enter image description here

    #编辑1

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

    提前谢谢。

    6 回复  |  直到 7 年前
        1
  •  5
  •   JAB    7 年前

    我不相信占位符的默认行为是可编辑的,但您试图完成的事情可以使用 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)
        }
    }
    

    在初始化时,可以将其扩展为获取颜色参数、字体等,或者您可能会发现它可以更简洁地生成子类 输入框

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

        2
  •  4
  •   Saranjith    7 年前

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

    当用户开始在textfield上输入时,在每个字符按下后留出一个空格。

    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
    }
    
        3
  •  2
  •   iamVishal16    7 年前

    我的解决方案是使用UITextField text属性

    +(BOOL)shouldChangeCharactersInRange:(NSRange)range
                       replacementString:(NSString *)string
                               textField:(UITextField *)textField
                                    mask:(NSString *)mask withMaskTemplate:(NSString *)maskTemplate{
    
        NSString * alreadyExistString = @"";
        if (string.length == 0) {
            alreadyExistString = textField.text;
            for (int i = range.location; i >= 0; i--) {
                unichar  currentCharMask = [maskTemplate characterAtIndex:i];
                unichar  currentChar = [alreadyExistString characterAtIndex:i];
                if (currentCharMask == currentChar) {// fixed value and _
                    continue;
                }else{
                    alreadyExistString = [alreadyExistString stringByReplacingCharactersInRange:NSMakeRange(i, 1) withString:@"_"];
                    break;
                }
            }
            textField.text = alreadyExistString;
            return NO;
        }else{
            alreadyExistString = [textField.text stringByReplacingCharactersInRange:NSMakeRange(range.location, 1) withString:string];
        }
    
        NSMutableString * validText = [[NSMutableString alloc] init];
    
        int last = 0;
        BOOL append = NO;
        for (int i = 0; i < alreadyExistString.length; i++) {
            unichar  currentCharMask = [mask characterAtIndex:i];
            unichar  currentChar = [alreadyExistString characterAtIndex:i];
            BOOL isLetter = [[NSCharacterSet alphanumericCharacterSet] characterIsMember: currentChar];
            BOOL isDigit  = [[NSCharacterSet decimalDigitCharacterSet] characterIsMember: currentChar];
            if ((isLetter && currentCharMask == '#') || (isDigit && currentCharMask == '9')) {
                [validText appendString:[NSString stringWithFormat:@"%c",currentChar]];
            }else{
                if (currentCharMask == '#' || currentCharMask == '9') {
                    break;
                }
                if ((isLetter && currentCharMask!= currentChar)|| (isDigit && currentCharMask!= currentChar)) {
                    append = YES;
                }
                [validText appendString:[NSString stringWithFormat:@"%c",currentCharMask]];
            }
            last = i;
        }
    
        for (int i = last+1; i < mask.length; i++) {
            unichar currentCharMask = [mask characterAtIndex:i];
            if (currentCharMask != '#' && currentCharMask != '9') {
                [validText appendString:[NSString stringWithFormat:@"%c",currentCharMask]];
            }
            if (currentCharMask == '#' || currentCharMask == '9') {
                break;
            }
        }
        if (append) {
            [validText appendString:string];
        }
    
        NSString *placeHolderMask = textField.text;
        NSString *sub = [validText substringWithRange:NSMakeRange(range.location, 1)];
        placeHolderMask = [placeHolderMask stringByReplacingCharactersInRange:NSMakeRange(range.location, 1) withString:sub];
        textField.text = placeHolderMask;
        return NO;
    }
    
    @property (nonatomic,strong) NSString * maskTemplate;// like: _2_-__-__A
    @property (nonatomic,strong) NSString * mask;// like: #2#-99-##A
    
    • 然后,当用户输入shouldChangeCharactersInRange调用时,它做得很好

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

    #编辑2

    • 无法更改单个文本颜色。类似字符串的@“_”下划线的颜色相同,输入字符的颜色相同。
    • 跟踪单个输入。

    仍在等待是否有任何其他使用占位符字符串的解决方法。

        4
  •  1
  •   VitorMM    7 年前

    我想这正是你想要的。创建您的 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;
    }
    

        5
  •  -1
  •   iamVishal16    7 年前

    在这种情况下,在swift-like-bellow中使用属性字符串,

    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)