Code Monkey home page Code Monkey logo

bonmot's Introduction

BonMot Logo

CI Status Version License Platform Carthage compatible

BonMot (pronounced Bon Mo, French for good word) is an iOS attributed string generation library. It abstracts away the advanced iOS typography tools, freeing you to focus on making your text beautiful.

To run the example project, run pod try BonMot, or clone the repo and open Example/BonMot.xcworkspace.

Installation with CocoaPods

BonMot is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'BonMot'

Installation with Carthage

BonMot is also compatible with Carthage. To install it, simply add the following line to your Cartfile:

github "Raizlabs/BonMot"

Supported Text Features

BonMot uses attributed strings to give you control over the following typographical features:

  • Font
  • Text color
  • Tracking (in either UIKit Points or Adobe-friendly thousandths of an em)
  • First line head indent
  • Head indent
  • Tail indent
  • Line height multiple
  • Maximum line height
  • Minimum line height
  • Line spacing
  • Paragraph spacing before
  • Paragraph spacing after
  • Baseline offset
  • Text alignment
  • Underlining and strikethrough
  • Figure case (uppercase vs. lowercase numbers)
  • Figure spacing (monospace vs. proportional numbers)
  • Inline Images with optional multi-line paragraph alignment

Think something is missing? Please file an issue (or add a +1 if one already exists).

Usage

In any file where you want to use BonMot, simply #import <BonMot/BonMot.h> or @import BonMot.

The basic object in BonMot is BONText. You create a text object, set some properties to configure the font, and then ask for its .attributedString to get a string formatted according to your specification. Or ask for .attributes if you just need the attributes dictionary:

NSString *quote = @"I used to love correcting people’s grammar until\
 I realized what I loved more was having friends.\n\
—Mara Wilson";

BONText *text = [BONText new];
text.font = [UIFont fontWithName:@"AmericanTypewriter" size:17.0f];
text.lineHeightMultiple = 1.8f;
text.string = quote;

NSAttributedString *string = text.attributedString;
NSDictionary *attributes = text.attributes;

Chaining Syntax

BONChain is a wrapper around BONText that allows you to chain properties together for a more concise expression of a style. You can create a chain with a normal [[BONChain alloc] init], but it's easier to just use [BONChain new] or the even shorter and technically valid BONChain.new:

NSString *quote = @"I used to love correcting people’s grammar until\
 I realized what I loved more was having friends.\n\
—Mara Wilson";

// line-wrapped for readability
NSAttributedString *attributedString =
BONChain.new // [BONChain new] and [[BONChain alloc] init] also work
.fontNameAndSize(@"AmericanTypewriter", 17.0f)
.lineHeightMultiple(1.8f)
.string(quote)
.attributedString;

You can also create a local variable or property to save a partially-configured chain. All the chaining methods pass copies of the chain, so you don't have to worry about later changes clobbering earlier properties:

// Base Chain
BONChain *birdChain =
BONChain.new
.lineHeightMultiple(1.2f)
.font([UIFont systemFontOfSize:17.0f])
.string(@"bird");

// Two chains with different colors
// that inherit their parents’ properties
BONChain *redBirds = birdChain.textColor([UIColor redColor]);
BONChain *blueBirds = birdChain.textColor([UIColor blueColor]);

// two different attributed strings with all attributes shared
// except for text color
NSAttributedString *redBirdString = redBirds.attributedString;
NSAttributedString *blueBirdString = blueBirds.attributedString;

Concatenation

You can concatenate an array of BONTexts:

BONText *oneFish = BONChain.new.string(@"one fish").text;
BONText *twoFish = BONChain.new.string(@"two fish").text;
BONText *redFish = BONChain.new.string(@"red fish").textColor([UIColor redColor]).text;
BONText *blueFish = BONChain.new.string(@"blue fish").textColor([UIColor blueColor]).text;
BONText *separator = BONChain.new.string(@", ").text;

NSAttributedString *string = [BONText joinTexts:@[ oneFish, twoFish, redFish, blueFish ] withSeparator:separator];

Outputs:

You can also append texts directly to each other:

NSString *commaSpace = @", ";
BONChain *chain = BONChain.new;
[chain appendLink:BONChain.new.string(@"one fish")];
[chain appendLink:BONChain.new.string(@"two fish") separator:commaSpace];
[chain appendLink:BONChain.new.string(@"red fish").textColor([UIColor redColor]) separator:commaSpace];
[chain appendLink:BONChain.new.string(@"blue fish").textColor([UIColor blueColor]) separator:commaSpace];

NSAttributedString *string = chain.attributedString;

Outputs:

(Notice that the comma after red fish is red, but in the previous example, it was not colored. This is the behavior that made the most sense to me, but please open an issue or pull request if you think it should be different.)

Image Attachments

BonMot uses NSTextAttachment to embed images in strings. Simply use the .image property of a chain or text:

BONChain *chain = BONChain.new;
[chain appendLink:BONChain.new.image(someUIImage).baselineOffset(-4.0f)];
[chain appendLink:BONChain.new.text(@"label with icon") separator: @" "];
NSAttributedString *string = chain.attributedString;

Outputs:

If you need to wrap multiple lines of text after an image, use the indentSpacer property to align the whole paragraph after the image:

NSString *quote = @"This is some text that goes on and on and spans multiple lines, and it all ends up left-aligned";
BONChain *chain = BONChain.new;
[chain appendLink:BONChain.new.image(someUIImage).indentSpacer(10.0f)];
[chain appendLink:BONChain.new.string(quote)];
NSAttributedString *attributedString = chain.attributedString;

Outputs:

Special Characters

You can easily access those hard-to-find special characters using the BONSpecial class. These include the No-Break Space, En and Em Spaces, various kinds of dashes, and more. If it’s hard to see in your source code or debug logs, it belongs in BONSpecial. If you want to add special characters to BonMot, add them to BONSpecialGenerator.swift (requires Xcode 7), run swift BONSpecialGenerator.swift, and submit a pull request! See SpecialCharactersCell.m in the sample project for some examples of how to use BONSpecial.

Vertical Text Alignment

UIKit lets you align labels by top, bottom, or baseline. BonMot includes BONTextAlignmentConstraint, a layout constraint subclass that lets you align labels by cap height and x-height. For some fonts, this is essential to convey the designer’s intention:

Illustration of different methods of aligning text vertically

BONTextAlignmentConstraint works with any views that expose a font property. It uses Key-Value Observing to watch for changes to the font property, and adjust its internal measurements accordingly. This is ideal for use with Dynamic Type: if the user changes the font size of the app, BONTextAlignmentConstraint will update. You can also use it to align a label with a plain view, as illustrated by the red dotted line views in the example above.

Warning: BONTextAlignmentConstraint holds strong references to its firstItem and secondItem properties. Make sure that a view that is constrained by this constraint does not also hold a strong reference to said constraint, because it will cause a retain cycle.

You can use BONTextAlignmentConstraint programmatically or in Interface Builder. In code, use the convenience initializer:

[BONTextAlignmentConstraint constraintWithItem:someLabel
                                     attribute:BONConstraintAttributeCapHeight
                                     relatedBy:NSLayoutRelationEqual
                                        toItem:someOtherLabel
                                     attribute:BONConstraintAttributeCapHeight].active = YES;

In Interface Builder, start by constraining two views to each other with a top constraint. Select the constraint, and in the Identity Inspector, change the class to BONTextAlignmentConstraint:

setting the class in the Identity Inspector

Next, switch to the Attributes Inspector. BONTextAlignmentConstraint exposes two text fields through IBInspectables. Type in the attributes you want to align. You will get a run-time error if you enter an invalid value.

setting the alignment attributes in the Attributes Inspector

The layout won’t change in Interface Builder (IBDesignable is not supported for constraint subclasses), but it will work when you run your code.

Note: some of the possible alignment values are not supported in all configurations. Check out Issue #37 for updates.

Contributing

Issues and pull requests are welcome! Please format all code using clang-format and the included .clang-format configuration file.

Author

Zev Eisenberg: mailto:[email protected], @ZevEisenberg

Logo by Jon Lopkin: @jonlopkin

License

BonMot is available under the MIT license. See the LICENSE file for more info.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.