Are There Any Analogues of [Nsstring Stringwithformat:] for Nsattributedstring

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

NSAttributedString from localized string with format specifier

1) Get your localized template using NSLocalizedString().

2) Get the text to insert.

3) Combine the two using -stringWithFormat:.

4) In the template, find the location of the placeholder using -rangeOfString:
5) Find the range of the inserted text in the formatted string, using the start position found in the last step, with -rangeOfString:options:range:. (The third argument here is the range within which to search; this avoids finding non-substituted text.)

6) Create an attributed string from the formatted string, using the range to apply attributes to the inserted text.

Iterating format % placeholders one by one

Big thanks to @Rick for pointing me in the right direction.

His post recommends first going over the arguments and pre-escaping any string or character objects before applying the format strings. This brought me back to another problem I was having earlier, in trying to iterate an argument list of different types (NSString, int etc), like NSLog does. I think I found that it is impossible (or at least really difficult) to do this, and the reason NSLog can is that it knows what types to expect through the format specifiers (%@, %i etc).

I realize I can actually get the same effect not by escaping the arguments, but by escaping the format string itself.

Example:

format: "test //italic %@//"
args: "text // more text"

Steps:

  1. First replace all instances of // with //-TAG-//
  2. Apply the arguments
  3. Determine where styling applies between //-TAG-//

Obviously //-TAG-// can still be written in the arguments to mess up the styling, however depending on what you use as a replacement, the chances of this happening are essentially zero.

NSString stringWithFormat - trying to set a label to double digits for single digit numbers

You were very close: try "%.2d" (note the ".").

The reference for the format string in the -stringWithFormat: method is the IEEE printf specification

Different font for parameters in NSLocalizedString

First, you should have in your .strings a much more generic and readble key, something like:

"_REPLIED_IN_" = "%@ has replied in %@";

Do not confuse keys and values as you seem to do in your example.
Also, it's easier later to see when there is an hardcoded string not localized in your code.

Now, there is an issue, because in English, it might be in that order, but not necessarily in other languages.

So instead:

"_REPLIED_IN_" = "%1$@ has replied in %$2@";

Now, I'll use the bold sample, because it's easier, but what you could do is use some custom tags to tell you that it needs to be bold, like HTML, MarkDown, etc.

In HTML:

"_REPLIED_IN_" = "<b>%1$@</b> has replied in <b>%$2@</b>";

You need to parse it into a NSAttributedString:

let translation = String(format: NSLocalizedString(format: "_REPLIED_IN_", comment: nil), userName, conversationTitle)
let attributedText = NSAttributedString.someMethodThatParseYourTags(translation)

It's up to you to choose the easiest tag format), according to your needs: easy to understand by translators, and easy to parse (CocoaTouch already has a HTML parser, etc.).

Is it possible to assign different attributes to different characters in a string in UITextView?Swift 3

There is a simple way to do this. Outside Xcode :)

Open TextEditor in MAC and paste your text into it and format it as per your requirement and again copy it.

Now Add your UITextView into your ViewController in Storyboard and make that textView Attributed.

Now Paste your formatted text there in the text field.

Check below screenshot for reference.

Sample Image

Sample Image

Hope this will help you.



Related Topics



Leave a reply



Submit