iOS - Emphasise with Bold Strings in Localizable.Strings

iOS - Emphasise with bold strings in Localizable.strings

You can actually use HTML tags with NSAttributedString. This is what I used:

static func convertFromHTMLString(_ input: String?) -> NSAttributedString? {
guard let input = input else { return nil }

guard let data = input.data(using: String.Encoding.unicode, allowLossyConversion: true) else { return nil }
return try? NSAttributedString(data: data, options: [NSAttributedString.DocumentReadingOptionKey.documentType : NSAttributedString.DocumentType.html], documentAttributes: nil)
}

So I convert an input string to raw data using UTF8 format. Then I use a constructor of attributed string with data using appropriate flags NSAttributedString.DocumentReadingOptionKey.documentType : NSAttributedString.DocumentType.html.

Get the index of a parameter in a NSLocalizedString

If you just want to bold each number in a string, you could look at using enumerateSubstringsInRange:options:usingBlock: to enumerate each word in the string and check if it's numeric (longLongValue). When you find numeric values the enumeration block provides you with the range so you know what to modify in your attributed string.

Making parts of text bold in SwiftUI

iOS 15+ (Swift 5.5 +)

SwiftUI has built-in support for rendering Markdown.

It is GitHub flavored markdown. AttributedString converts both inline and block styles. SwiftUI renders inline styles (but not images at this time). We use the fantastic cmark-gfm library to parse the markdown string. - SwiftUI Frameworks Engineer - developer.apple.com

See more:

What is Markdown?


Use double asterisks (**) arroud the characters that you want to make bold.

Text("**CO**rona**V**irus **D**isease of 20**19**")

Use underscore (_) arround the charachters you want to make italic.

Text("Is this text _emphasized_?")

String variable

Use init(_ value: String)

Creates a localized string key from the given string value.

let bold = "This text is **bold**"
Text(.init(bold))

String interpolation

Use init(_ value: String)

Creates a localized string key from the given string value.

let bold = "Bold"
Text(.init("This text is **\(bold)**"))

Attributed text

Use init(_ attributedContent: AttributedString)

Creates a text view that displays styled attributed content.

let markdownText = try! AttributedString(markdown: "This text is **bold**")
Text(markdownText)

See also:

init(_ attributedContent: AttributedString) - https://developer.apple.com

Are there any analogues of [NSString stringWithFormat:] for NSAttributedString

I was looking for good existing solution for this question, but no success.

So I was able to implement it on my own.

That's why I am self-answering the question to share the knowledge with community.

Solution

NSAttributedString+VPAttributedFormat category provides methods for building attributed string based on attributed format and arguments that should satisfy this format.

The most suitable case of using this category is text controls with variable attributed text configured in interface builder.

You need set correct string format to attributed text and configure necessary attributes.

Then you need pass necessary arguments in code by using methods of this category.

  • Format syntax is the same as in [NSString stringWithFormat:] method;
  • Can be used in Objective C and Swift code;
  • Requires iOS 6.0 and later;
  • Integrated with CocoaPods;
  • Covered with unit tests.

Usage

1. Import framework header or module

// Objective C
// By header
#import <VPAttributedFormat/VPAttributedFormat.h>

// By module
@import VPAttributedFormat;


// Swift
import VPAttributedFormat

2. Set correct format and attributes for text control in interface builder

usage

3. Create IBOutlet and link it with text control

// Objective C
@property (nonatomic, weak) IBOutlet UILabel *textLabel;


// Swift
@IBOutlet weak var textLabel: UILabel!

4. Populate format with necessary arguments

// Objective C
NSString *hot = @"Hot";
NSString *cold = @"Cold";

self.textLabel.attributedText = [NSAttributedString vp_attributedStringWithAttributedFormat:self.textLabel.attributedText,
hot,
cold];


// Swift
let hot = "Hot"
let cold = "Cold"
var arguments: [CVarArgType] = [hot, cold]
textLabel.attributedText = withVaList(arguments) { pointer in
NSAttributedString.vp_attributedStringWithAttributedFormat(textLabel.attributedText, arguments: pointer)
}

5. See result

result

Examples

VPAttributedFormatExample is an example project. It provides Basic and Pro format examples.

example

Make part of a UILabel bold in Swift

You will want to use attributedString which allows you to style parts of a string etc. This can be done like this by having two styles, one normal, one bold, and then attaching them together:

let boldText = "Filter:"
let attrs = [NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 15)]
let attributedString = NSMutableAttributedString(string:boldText, attributes:attrs)

let normalText = "Hi am normal"
let normalString = NSMutableAttributedString(string:normalText)

attributedString.append(normalString)

When you want to assign it to a label:

label.attributedText = attributedString

Exceeding max Text() concatenation length - SwiftUI -

Hmm... unexpected limitation... anyway - learn something new.

Ok, here is improved algorithm, which should move that limitation far away.

Tested with Xcode 12 / iOS 14. (also updated code in referenced topic Highlight a specific part of the text in SwiftUI)

func hilightedText(str: String, searched: String) -> Text {
guard !str.isEmpty && !searched.isEmpty else { return Text(str) }

var result = Text("")

var range = str.startIndex..<str.endIndex
repeat {
guard let found = str.range(of: searched, options: .caseInsensitive, range: range, locale: nil) else {
result = result + Text(str[range])
break
}

let prefix = str[range.lowerBound..<found.lowerBound]
result = result + Text(prefix) + Text(str[found]).bold().foregroundColor(.yellow)

range = found.upperBound..<str.endIndex
} while (true)

return result
}

demo



Related Topics



Leave a reply



Submit