2022-12-30

How do I mirror an NSAttributedString with an icon and text in right-to-left mode

I have a UIButton that holds an NSAttributedString that contains an icon (which is an NSAttributedString itself) followed by a text.

It looks something like this:

Button appearance in LTR

I want to make it look like this when the device is configured for an RTL language (e.g. Arabic, Hebrew):

Desired look in RTL mode

The string is built like this:

var iconText = NSAttributedString(fontName: fontName, fontSize: fontPointSize, fontValue: fontValue, color: color ?? iconColor)
let iconTextRange = NSRange(location: 0, length: iconText.count)
let iconAttrs: [NSAttributedString.Key: Any] = [.font: icon.font(pointSize: pointSize),
                                                .foregroundColor: iconColor]

if !text.isEmpty {
    iconText = "\(iconText) \(text)"
}

let attributeString = NSMutableAttributedString(string: iconText, attributes: textAttrs)
attributeString.addAttributes(iconAttrs, range: iconTextRange)
return attributeString

As you can see, first the icon is created using a font, then it's concatenated to the text.

In other parts of the app, I managed to make NSAttributedString's RTL-compliant with this little piece of code:

public extension NSAttributedString {
    /// Returns an identical attributed string that'll adjust its direction based on the device's configured language.
    func rightToLeftAdjusted() -> NSAttributedString {
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.baseWritingDirection = .natural
        
        let attrs: [NSAttributedString.Key: Any] = [.paragraphStyle: paragraphStyle]
        let range = NSRange(location: 0, length: length)
        
        let copy = NSMutableAttributedString(attributedString: self)
        copy.addAttributes(attrs, range: range)
        
        return copy
    }
}
    

Unfortunately, in this specific case, it doesn't seem to work, the star ALWAYS stays to the left of the text.

Are there any other ways of achieving this?



No comments:

Post a Comment