- Notifications
You must be signed in to change notification settings - Fork 0
If you have ever tried to work with the Objective-C Framework class NSAttributedString you know that it can be labor intensive. If you are assembling even a few paragraphs, there are a lot of steps involved.
This is a job for a builder!
SimpleText aims to be a builder that provides a subset of the functionality of the Foundation and AppKit frameworks around creating NSAttributedString objects.
The goal of SimpleText is to provide tools to reduce the boilerplate code you write when you are hacking together a NSAttributedString object.
To do this, we may sacrifice some of the flexibility provided by the Foundation and AppKit frameworks. The frameworks provide a lot more functionality but the goal of SimpleText is to provide an easy way to handle common use-cases. These are the cases we cover:
- Paragraph alignment (left, right, center, justified)
- Handling bold, italic, and underline styles
- Setting a font size
- Applying base font names and falling back seamlessly if there is no match
- Adding a hyperlink
This project targets iOS, but we will try to cover OS X as well.
The API is broken into messages that set attributes at three levels: Document, Paragraph, and Phrase. Messages at the document level, remain in effect until they are overwritten. Paragraph level messages remain in effect until writeParagraph is called. Phrase level messages remain in effect until write or writeParagraph is called.
// Document level methods
-(STAttributedStringBuilder*) fontFamily:(NSString*)fontFamilyName withSize:(CGFloat)size;
// Paragraph level attributes
-(STAttributedStringBuilder*) left;
-(STAttributedStringBuilder*) center;
-(STAttributedStringBuilder*) right;
-(STAttributedStringBuilder*) justified;
// Phrase level attributes
-(STAttributedStringBuilder*) bold;
-(STAttributedStringBuilder*) underline;
-(STAttributedStringBuilder*) italics;
// Writes the provided text to the buffer and clears phrase level settings
-(STAttributedStringBuilder*)write:(NSString*)string;
-(STAttributedStringBuilder*)write:(NSString*)string withLink:(NSString*)uri;
// Writes the provided text to the buffer and clears paragraph and phrase level settings
-(void)writeParagraph:(NSString*)string;
// Build the NSAttributedString
-(NSAttributedString*)build;
SimpleText has a category for NSAttributedString that adds an initializer. The purpose of the category is to remove the boilerplate code necessary to instantiate the builder and build the NSAttributedString. You pass in a domain object of your own which is, in turn, provided to your callback block. The callback block is called with a builder ready to go. After the callback is executed, the builder's build message is invoked which builds the NSAttributedString.
+(instancetype)st_attributedStringWithObject(id)object builderHandler:(void (^) (STAttributedStringBuilder *builder, id object)) builderBlock;
// Or, if you have no domain object
+(instancetype)st_attributedStringWithBuilderHandler:(void (^) (STAttributedStringBuilder *builder, id object)) builderBlock;
For now, ignore how you get an instance of the builder. This example shows how you center text:
// Tell the builder we want the next paragraph to be centered
[builder center];
// Write out the text
[builder writeParagraph: @"How The West Was Won"];
When you call writeLine, it flushes the paragraph scoped commands.
Many methods return the builder instance so you can combine the previous statements like this:
[[builder center] writeParagraph: @"How The West Was Won"];
To italicize one word in a sentence:
[[[[builder write:@"This "] italics] write:@"is"] writeParagraph@" neat!"];
Writes:
This is neat!
Here is a complete example that uses the extension:
#import "SimpleText/SimpleText.h"
...
MyDomainObject *do = [[MyDomainObject alloc] init];
do.firstName = @"Steve";
do.salary = 100.00;
NSAttributedString *doc = [NSAttributedString st_attributedStringWithObject:do builderHandler:^(STAttributedStringBuilder *builder, id object)
{
[[builder center] writeParagraph:@"Employee Salary Report"];
[[[builder bold] write:@"Name: "] writeParagraph:[do getFirstName]];
[[[builder bold] write:@"Salary: "] writeParagraph:[do getSalary]];
}
];