Search code examples
iosuitextfieldnsattributedstring

Adding NSMutableAttributedString into a TextField


I have a custom UITextfield which I want when the user finishes typing, a small "R$" must be added at the begging of the text with different size.

I call the method to add the "R$" like this:

self.addTarget(self, action: #selector(setCurrencyLabelPosition), for: .editingDidEnd)

and then I try to change the attributes and content like this:

 func setCurrencyLabelPosition(){

        let fullText:String = "R$\((self.text)!)"
        self.text = fullText
        var attribute:NSMutableAttributedString = NSMutableAttributedString(attributedString:self.attributedText!)
        attribute.addAttribute(NSFontAttributeName, value:UIFont.systemFont(ofSize: 12), range: NSRange(location:  0, length: 2))
        self.attributedText = attribute

    }

the original text of this textfield is set for size 40.0, I want only the "R$" to be of size 12.0

The problem I'm facing is that the whole text gets the size 40.0 It prints the "R$" but the size of 40.

Is it possible to do what I'm trying to using NSMutableAttributedString?


Solution

  • I had been working on your question, I think there is a bug in UITextField because if you modify the font to bigger font it works but if you do so but for small font then don't work.

    I have done a custom class and added some customizable Inspectable properties, hope this finally help you

    This is how looks, Note: the glitch is because of my gif converter enter image description here

    import UIKit
    
    @IBDesignable
    class CustomTextField: UITextField {
    
        @IBInspectable var prefix : String = ""
        @IBInspectable var removePrefixOnEditing : Bool = true
    
        override init(frame: CGRect) {
            super.init(frame: frame)
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
        }
    
        override func awakeFromNib() {
            super.awakeFromNib()
            self.addTarget(self, action: #selector(setCurrencyLabelPosition), for: .editingDidEnd)
            self.addTarget(self, action: #selector(removePrefix), for: .editingDidBegin)
        }
    
        func removePrefix(){
            if self.attributedText != nil
            {
                if(self.removePrefixOnEditing)
                {
                    self.defaultTextAttributes = [NSFontAttributeName : UIFont.systemFont(ofSize: 20)]
                    let prefixRange = NSString(string: (self.attributedText?.string)!).range(of: prefix)
                    if(prefixRange.location != NSNotFound)
                    {
                        self.attributedText = NSAttributedString(string: (self.attributedText?.string.replacingOccurrences(of: prefix, with: ""))!, attributes: self.defaultTextAttributes)
                    }
                }
            }
        }
    
        func setCurrencyLabelPosition(){
    
            if self.attributedText != nil
            {
                var fullText:String = "\((self.attributedText?.string)!)"
                if(NSString(string: (self.attributedText?.string)!).range(of: prefix).location == NSNotFound)
                {
                    fullText = "\(prefix)\((self.attributedText?.string)!)"
                }
                //hacky part, seems to be a bug in UITextField
                self.defaultTextAttributes = [NSFontAttributeName : UIFont.systemFont(ofSize: 10)]
                self.attributedText = NSAttributedString(attributedString: self.changeFontForText(originalText: fullText, text: prefix, basicFont: UIFont.systemFont(ofSize: 20), newFont: UIFont.systemFont(ofSize: 12)))
            }
        }
    
        func changeFontForText(originalText:String,text:String,basicFont:UIFont, newFont:UIFont) -> NSMutableAttributedString
        {
            let resultAttributedString = NSMutableAttributedString(string: originalText, attributes: [NSFontAttributeName : basicFont])
            let range = NSString(string: originalText).range(of: text)
            if(range.location != NSNotFound)
            {
                resultAttributedString.setAttributes([NSFontAttributeName:newFont], range: range)
            }
    
            return resultAttributedString
        }
    
    }
    

    Hope this helps