簡體   English   中英

如何設置 UITextField 的字母間距

[英]How to set letter spacing of UITextField

我有一個應用程序,用戶必須在其中鍵入一個四位數的密碼。 所有數字必須彼此保持一定距離。

如果PinTextFieldUIView的子類,有沒有辦法做到這一點? 我知道在ViewController您可以使用UITextFieldTextDidChangeNotification並為每個更改設置屬性文本。 通知似乎在UIView不起作用。

另外,我想知道如果要設置UITextField文本的字母間距,是否沒有比為每次更新制作屬性字符串更簡單的方法?

正確間距:

具有正確間距的 TextField

錯誤的間距:

間距錯誤的文本字段

不需要去attributedText ,老實說,用修改后的間距實現是一團糟。 我一合上鍵盤,間距就消失了,這促使我進一步挖掘。

每個 UITextField 都有一個名為defaultTextAttributes的屬性,根據 Apple 的說法,它“返回具有默認值的文本屬性字典”。 . Apple 文檔還說“此屬性將指定的屬性應用於文本字段的整個文本”

只需在您的代碼中找到合適的位置,通常是初始化文本字段的位置,然后復制並粘貼以下內容。

在 Swift 3.0 中回答

textfield.defaultTextAttributes.updateValue(spacing, forKey: NSKernAttributeName)

其中間距是 CGFloat 類型。 例如 2.0

這也適用於不同的字體。

干杯!!


最新的語法似乎是:

 yourField.defaultTextAttributes.updateValue(36.0, 
     forKey: NSAttributedString.Key.kern)

這就是最終為每次更改設置字距的方法

    textField.addTarget(self, action: "textFieldDidChange", forControlEvents: .EditingChanged)

    func textFieldDidChange () {    
        let attributedString = NSMutableAttributedString(string: textField.text)
        attributedString.addAttribute(NSKernAttributeName, value: 5, range: NSMakeRange(0, count(textField.text)))
        attributedString.addAttribute(NSFontAttributeName, value: font, range: NSMakeRange(0, count(textField.text)))
        attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.blackColor(), range: NSMakeRange(0, count(textField.text)))

        textField.attributedText = attributedString
    }

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

        if count(textField.text) < 4 {
            return true
            // Else if 4 and delete is allowed
        }else if count(string) == 0 {
            return true
            // Else limit reached
        }else{
            return false
        }
    }

然而問題仍然存在,因為不同的數字具有不同的寬度,我將回到為每個數字制作一個UITextField

使用UITextFielddefaultTextAttributes屬性。 它將為您處理到NSAttributedString的轉換並應用您設置的屬性。 例如:

    NSMutableDictionary *attrs = [self.textField.defaultTextAttributes mutableCopy];
[attrs addEntriesFromDictionary:@{
    NSKernAttributeName: @18,
    NSUnderlineColorAttributeName: [UIColor grayColor],
    NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle | NSUnderlinePatternDash)
}];
self.textField.defaultTextAttributes = attrs;

不太確定任何其他解決方案,而不是使用屬性字符串。

但是對於通知部分,您可以將textFields委托設置為UIView並在視圖中定義以下方法。

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string; 

每次在文本字段中輸入的文本更改時都會調用上述方法。

在將委托設置為文本字段后試試這個代碼。希望它會起作用。

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:textField.text];
    [attributedString addAttribute:NSKernAttributeName
                             value:@(5.4)
                             range:NSMakeRange(0, textField.text.length)];
    textField.attributedText = attributedString;
    return YES;
}

這在 Swift 2.2 中運行良好。 希望這對您在文本字段中的字母間距有所幫助

override func viewDidLoad() {
 // Do any additional setup after loading the view.
        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(SignupVC.limitTextField(_:)), name: "UITextFieldTextDidChangeNotification", object: txtContactNumber)
}
 func limitTextField(Notif:NSNotification) {

    let limit=10;

    let attributedString = NSMutableAttributedString(string: txtContactNumber.text!)
    attributedString.addAttribute(NSKernAttributeName, value: 7, range: NSMakeRange(0, (txtContactNumber.text?.characters.count)!))
   // attributedString.addAttribute(NSFontAttributeName, value: font, range: NSMakeRange(0, count(textField.text)))
    attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.blackColor(), range: NSMakeRange(0,(txtContactNumber.text?.characters.count)!))

    txtContactNumber.attributedText = attributedString
    if(txtContactNumber.text?.characters.count>limit)
    {
        txtContactNumber.text=txtContactNumber.text?.substringToIndex(limit)
    }
}

需要計算每個字符的字距並將其刪除為最后一個字符。 Swift 5.3 上有示例

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
    let maxLength = 6
    let symbolWidth = CGFloat(43)
    let font = UIFont.systemFont(ofSize: 30)
    
    if string == "" { // when user remove text
        return true
    }
        
    if textField.text!.count + string.count - range.length > maxLength { // when user type extra text
        return false
    }
    
    let currentText = NSMutableAttributedString(attributedString: textField.attributedText ?? NSMutableAttributedString())
    currentText.deleteCharacters(in: range) // delete selected text
    var newStringLength = 0 
    
    for char in string{
        let newSymbol = NSMutableAttributedString(string: String(char))
        newSymbol.addAttribute(.font, value: font, range: NSMakeRange(0, 1))
        let currentSymbolWidth = newSymbol.size().width
        let kern = symbolWidth - currentSymbolWidth
        newSymbol.addAttribute(.kern, value: kern, range: NSMakeRange(0,1))
        
        currentText.insert(newSymbol, at: range.location + newStringLength)
        newStringLength += 1
    }
    
    if currentText.length == maxLength{
        currentText.addAttribute(.kern, value: 0, range: NSMakeRange(maxLength - 1, 1))
    }
    
    textField.attributedText = currentText
    
    return false

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM