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

你能帮我么。

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

在此处输入图像描述

#EDIT 1

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

提前致谢。

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

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

自定义占位符文本字段

 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变量将返回用户在任何给定点输入的文本。 此外,使用固定宽度字体将消除用户键入和替换占位符文本时的抖动。

不使用占位符文本,而是在文本字段下方使用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 } 

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

 +(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并且它做得很好

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

#Edit 2

我遇到的问题接近了

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

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

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

 -(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; } 

它应该按预期工作。

对于那种情况,使用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) 

否如果没有在UITextfield上创建自定义图层之后你不能这样做,你需要检查输入的字符是否与placehoder字符串匹配,然后只更换字符。 另请参阅替换UITextField中每种类型后的字符?