Search code examples
iosobjective-cswiftnsattributedstring

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


Usually I build app interface in interface builder. Sometimes design requires to use attributed strings (fonts, colors and etc.). It's easy to configure if string is static.
But if string is dynamic (format with arguments) then there are no ways to configure attributes in interface builder. It requires to write a lot of code.
I am looking for some analogues of [NSString stringWithFormat:] for NSAttributedString. So I will be able to set string format and necessary attributes in interface builder, and then provide necessary arguments in code.

For example:
Let's consider that I need display string with such format: "%d + %d = %d" (all numbers are bold).
I want to configure this format in interface builder. In code I want to provide arguments: 1, 1, 2. App should show "1 + 1 = 2".


Solution

  • 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