2017-09-05 42 views
18

您能否幫助我。如何實現佔位符文本在UITextField中逐個字符地消失

UITextField當我們提供佔位符文本時,其佔位符字符串將在我們輸入任何字符時消失。我怎樣才能實現只有輸入的字符將不會完整的字符串?這意味着如果我輸入3個字符,則只有佔位符的前3個字符將會消失。

enter image description here

#EDIT 1

此外,新輸入的字符文本的顏色會改變,其他剩餘的字符文本顏色保持不變。

在此先感謝。

+1

不需要佔位符,創建覆蓋和設置相同的文本文件的邊界,基於文本字段它會自動隱藏 –

+0

雅...這是一個技巧,但我想通過重寫默認的佔位符屬性來實現代碼。謝謝。 – Vishal16

+0

@ Anbu.Karthik其實你的解決方案不工作時,我想,以取代「_」下劃線與像「A」或「10」的特定字符再有就是在字符串中的不匹配。 – Vishal16

回答

2

我不相信佔位符的默認行爲是可編輯的,但您試圖完成的操作可以使用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變量將返回用戶在任何給定點輸入的文本。此外,使用固定寬度的字體將消除用戶輸入和替換佔位符文本時的不穩定性。

+0

偉大的工作。謝謝 – Vishal16

-3

否你不能在UITextfield上創建一個自定義圖層後做這個工作,因爲你需要檢查輸入的字符與placehoder字符串是否匹配,那麼只有替換字符。 也Replacing character after each type in UITextField?

+0

好的。我會嘗試但我想要替換佔位符個別文本。當我們輸入任何輸入字符時,您可以看到完整的佔位符字符串消失了。我想覆蓋它的默認行爲。 – Vishal16

+0

好吧,我正在做一個演示請等待,如果可以的話,我還原你。 –

2

有使用的UITextField text屬性

當用戶進入輸入shouldChangeCharactersInRange調用
+(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 
  • 最初設置文本字段中的文本,以掩蓋模板
  • 然後我的解決方案,它做了偉大的工作,看

#編輯1 我還實現了一些將光標移動到下劃線位置的代碼。如果有人需要幫助。請評論我會幫你。我一直在使用面向

#Edit 2

這個問題走近

  • 無法更改個別文本顏色。顏色與@「_」下劃線這兩個字符串的顏色相同,並且輸入字符具有相同的顏色。
  • 如果用戶沒有提供任何輸入,那麼我必須提供一個檢查以字符串形式發送空白。
  • 跟蹤個別輸入。

謝謝, 如果使用佔位符字符串還有其他解決方法,仍在等待。

3

不是使用佔位符文本,而是在文本字段下面使用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 
} 
+0

好的。好的解決方案,但我正在等待更多的迴應,但如果沒有其他方式來做這件事情。我會接受你的回答 – Vishal16

+0

快樂編碼曼:) – Saranjith

-1

對於像波紋管迅速這種情況下使用屬性串,

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) 
+0

沒有解決方案歸因當我們輸入任何輸入時,PlacholderString將會消失。 – Vishal16

1

我想這就是你要找的。使用文本_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; 
} 

它應該工作打算。