Declarative text styles and streamlined Dynamic Type support for iOS

Overview

    StyledText   BuddyBuild

StyledText is a library that simplifies styling dynamic text in iOS applications. Instead of having to use attributed strings every time you need to update text, you can declaratively set a text style on your labels. When the text of the label is updated, the label uses the preset style.

Before

let label = UILabel()
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 4.0
let attributes: [String: Any] = [NSFontAttributeName: UIFont.boldSystemFont(ofSize: 14),
                                 NSForegroundColorAttributeName: UIColor.blue,
                                 NSKernAttributeName: 1.5,
                                 NSParagraphStyleAttributeName: paragraphStyle]

let string = NSAttributedString(string: "This is a string",
                                attributes: attributes)
label.attributedText = string
let newString = NSAttributedString(string: "This is a new string",
                                   attributes: attributes)
label.attributedText = newString

After

let styledLabel = StyledLabel()
styledLabel.textStyle = TextStyle(font: .boldSystemFont(ofSize: 14), color: .blue, lineSpacing: 4.0, kern: 1.5)
styledLabel.text = "This is a string"
styledLabel.text = "This is a new string"

Installation

  1. Add this line to your Podfile:
pod "StyledText"
  1. Run a pod install
  2. You're all set!

How to Use

Getting started with StyledText is easy, just add a StyledLabel to your view and provide it with a TextStyle. After that, it behaves like any other UILabel. Changes to the label's text property will always use the set textStyle.

class ViewController: UIViewController {
    private let styledLabel: StyledLabel = {
        let label = StyledLabel(frame: .zero)
        label.textStyle = TextStyle(font: .boldSystemFont(ofSize: 24.0),
                                    color: .orange)
        return label
    }()
}

TextStyle

A TextStyle represents the attributes a styled view should use to draw its text. Many different text formatting options are supported, including those that previously required interaction with attributed strings or paragraph styles, such as kerning and line spacing. Creating a TextStyle is easy, just specify a font along with any other attributes you want to define. Any unspecified attributes simply remain as system defaults.

let style = TextStyle(font: .italicSystemFont(ofSize: 72),
                      color: .magenta,
                      lineSpacing: 10,
                      lineHeightMultiple: 2.0,
                      kern: -0.5,
                      alignment: .left,
                      lineBreakMode: .byTruncatingMiddle)

let blueStyle = style.with(color: .blue)
let redStyle = style.with(color: .red)

Providing Defaults

You probably have a sensible default value for kerning that works well for your font. Instead of needing to specify this kern value in each individual TextStyle you create, you can use a TextStyleDefaultsGenerator to add it automatically. The simplest way to get started with this is to extend TextStyle to conform to the TextStyleDefaultsGenerator protocol, the library will detect if you've added this conformance and behave appropriately.

extension TextStyle: TextStyleDefaultsGenerator {
    private static let defaultCeraKern: CGFloat = -0.2
    private static let defaultChronicleKern: CGFloat = -0.2

    static public func defaultKern(for font: UIFont) -> CGFloat? {
        if font.fontName.contains("Cera") {
            return defaultCeraKern
        } else if font.fontName.contains("Chronicle") {
            return defaultChronicleKern
        }
        return nil
    }
}

Dynamic Type Support

StyledText supports scaling text content to the system font size, a feature Apple calls Dynamic Type. To use this feature, set the dynamicTypeBehavior property of a TextStyle to one of these values:

  • noScaling: [default] keep the font size constant, even when the system font size changes
  • scaleToStandardSizes: scale the font to all standard system font sizes, larger accessibility sizes are capped at the maximum standard size
  • scaleToAllSizes: scale the font to all standard and accessiblity font sizes

It's possible for the font size to change while your application is running. When this occurs, you'll need to call refreshStyle() on any styled components that are visible for the size to update. A good way to listen for this event is by adding a delegate to the shared DynamicTypeController:

class MyViewController: UIViewController, DynamicTypeControllerDelegate {
    let label: StyledLabel = {
        let label = StyledLabel()
        label.textStyle = TextStyle(font: .boldSystemFont(ofSize: 14), color: .black, dynamicTypeBehavior: .scaleToStandardSizes)
        return label
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        DynamicTypeController.shared.addDelegate(self)
    }

    func preferredContentSizeCategoryDidUpdate(controller: DynamicTypeController, newCategory: UIContentSizeCategory){
        label.refreshStyle()
    }
}

Styled Components

To enable automatic styling, StyledText uses a number of view subclasses that are simple swap-in replacements for conventional UIKit components.

StyledText View Replaces UIKit View
StyledLabel UILabel
StyledTextView UITextView
StyledButton* UIButton

[*] Using StyledButton

StyledButton provides text style properties for each UIControlState button state.

Control State Text Style Property
.normal normalTextStyle
.highlighted highlightedTextStyle
.disabled disabledTextStyle
.selected selectedTextStyle

License

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

Comments
  • Added Carthage support and upgraded to Swift 4

    Added Carthage support and upgraded to Swift 4

    Description

    • Upgraded to Swift 4.
    • Added an Xcode project with a shared build scheme so Carthage is able to build a dynamic framework.
    • Updated README.md to reflect new installation option.
    • Tested everything from my personal fork.

    After merge

    Please tag this as a stable release on GitHub so Carthage will be able to find it. Carthage determines which versions of framework are available by searching through the tags published on the repository, and trying to interpret each tag name as a semantic version. For example, in the tag v1.2, the semantic version is 1.2.0.

    opened by gapl 6
  • Implement Dynamic Type support

    Implement Dynamic Type support

    This PR implements Dynamic Type support.

    TextStyle has a new parameter to define whether it should scale to the system font size.

    DynamicTypeController is a new class that handles both system-wide and app-specific font size category definition and changes. There is a shared instance available for default usage.

    More advanced cases are enabled by setting the controller property of your TextStyle to a custom DynamicTypeController that you can customize independently of the default shared instance. This would allow a specific screen in your app to have it's own font size slider, for example.

    opened by huebnerob 1
  • Fixed pods and re-recorded snapshots with new system fonts

    Fixed pods and re-recorded snapshots with new system fonts

    • Fixed building example project by re-installing pods
    • After examination of the snapshot diffs, the snapshots were re-recorded as the failures seem to result form system font changes
    opened by dtaylor1701 0
  • Update sample project for Xcode 9 and Swift 4.0

    Update sample project for Xcode 9 and Swift 4.0

    Summary

    This branch updates the StyledText sample project to enable successful building, running, and testing with Xcode 9 and Swift 4.0

    Implementation Details

    • Updated to newest versions of Nimble, Quick, and Nimble-Snaphots
    • Set Swift version to 4.0 in build settings (no code changes were necessary 🎉)
    opened by huebnerob 0
  • Sample Project does not build on Xcode 9.0

    Sample Project does not build on Xcode 9.0

    The sample project no longer compiles on Xcode 9. We either need to (ideally) migrate to Swift 4 or (less ideally) update the project settings such that Swift 3 is used to compile.

    opened by huebnerob 0
  • Snapshot testing

    Snapshot testing

    This branch uses FBSnapshotTestCase and Nimble-Snapshots to add snapshot tests to StyledLabel. Check out StyledLabelSpec to see them in action. The views initialized there are compared with snapshots stored in Example/Tests/ReferenceImages/StyledLabelSpec/, you can view all the raw images there.

    opened by huebnerob 0
Releases(v1.4.0)
Owner
Blue Apron
Blue Apron provides you with all the ingredients that you need to make a delicious meal in exactly the right proportions.
Blue Apron
Focus text field in SwiftUI dynamically and progress through form using iOS keyboard.

Focuser Focuser allows to focus SwiftUI text fields dynamically and implements ability move go through the form using Keyboard for iOS 13 and iOS 14.

Art Technologies 118 Dec 25, 2022
A beautiful and flexible text field control implementation of "Float Label Pattern". Written in Swift.

SkyFloatingLabelTextField SkyFloatingLabelTextField is a beautiful, flexible and customizable implementation of the space saving "Float Label Pattern"

Skyscanner 4k Jan 1, 2023
Currency text field formatter available for UIKit and SwiftUI 💶✏️

CurrencyText provides lightweight libraries for formating text field text as currency, available for both UIKit and SwiftUI. Its main core, the Curren

Felipe Lefèvre Marino 183 Dec 15, 2022
Changes the color of the label text when the button is pressed and also prints hello to the console

MY FIRST APP App Description This app changes the color of the label text when the button is pressed and also prints "hello" to the console. App Walk-

null 0 Nov 29, 2021
UITextField and UITextView subclasses with placeholders that change into floating labels when the fields are populated with text.

Deprecated Please use JVFloatLabeledTextField instead or feel free to chime in on an issue if you'd like to take over the repo. RPFloatingPlaceholders

rob phillips 1.1k Jan 5, 2023
A text view that supports selection and expansion

The Problem UILabel and UITextView offer unsatisfying support for text selection. Existing solutions like TTTAttributedLabel are great but offer a som

Jeff Hurray 636 Dec 20, 2022
Lightweight set of text fields with nice animation and functionality

TweeTextField This is lightweight library that provides different types of Text Fields based on your needs. I was inspired by Jan Henneberg. Features

Oleg 471 Nov 10, 2022
RichTextKit is a Swift-based library for working with rich text in UIKit, AppKit and SwiftUI.

About RichTextKit RichTextKit is a Swift-based library that lets you work with rich text in UIKit, AppKit and SwiftUI. RichTextKit is under developmen

Daniel Saidi 282 Dec 28, 2022
AEOTPTextField - A beautiful iOS OTP Text Field library, written in Swift with full access customization in UI.

AEOTPTextField - A beautiful iOS OTP Text Field library, written in Swift with full access customization in UI.

Abdelrhman Kamal 79 Jan 3, 2023
A SwiftUI TextField with a prompt (or placeholder) that floats above the text field when active or not empty. Requires iOS 15.

FloatingPromptTextField A prompt is the label in a text field that informs the user about the kind of content the text field expects. In a default Tex

Emilio Peláez 43 Nov 3, 2022
Transition from any SwiftUI Text view into an inline navigation bar title when the view is scrolled off-screen, as seen in Apple's TV & TestFlight iOS apps.

SwiftUI Matched Inline Title Transition from any SwiftUI Text view into an inline navigation bar title when the view is scrolled off-screen, as seen i

Seb Jachec 19 Oct 9, 2022
An UITextView in Swift. Support auto growing, placeholder and length limit.

GrowingTextView Requirements iOS 8.0 or above Installation CocoaPods GrowingTextView is available through CocoaPods. To install it, simply add the fol

Kenneth Tsang 941 Jan 5, 2023
Provides a SwiftUI multi-line TextView implementation including support for auto-sizing. (iOS)

TextView Also available as a part of my SwiftUI+ Collection – just add it to Xcode 13+ Provides a SwiftUI multi-line TextView implementation with supp

SwiftUI+ 51 Jan 3, 2023
Custom emoji rendering library for iOS apps with support for GIF & still images

Custom emoji rendering library for iOS apps with support for GIF & still images - plug-in extension for UITextView - performance, cache ✅ - Made with ?? by @GetStream

Stream 244 Dec 11, 2022
SwiftUI TextEdit View - A proof-of-concept text edit component in SwiftUI & CoreText.

A proof-of-concept text edit component in SwiftUI & CoreText. No UIKit, No AppKit, no UITextView/NSTextView/UITextField involved.

Marcin Krzyzanowski 80 Dec 1, 2022
Render Markdown text in SwiftUI

MarkdownUI MarkdownUI is a library for rendering Markdown in SwiftUI, fully compliant with the CommonMark Spec. Supported Platforms You can use the Ma

Guille Gonzalez 916 Jan 8, 2023
Autocomplete for a text field in SwiftUI using async/await

Autocomplete for a text field in SwiftUI using async/await

Dmytro Anokhin 13 Oct 21, 2022
ExpandableText 😎 (SwiftUI) Expand the text with the "more" button

ExpandableText ?? (SwiftUI) Expand the text with the "more" button Get Started import SwiftUI import ExpandableText struct ExpandableText_Test: View

null 35 Dec 26, 2022
Handles some of the base configuration to make creating a UIAlertController with text entry even easier. Plus validation!

?? FancyTextEntryController A simpler/easier API for adding text fields to UIAlertControllers. Not a custom view, just uses good ol' UIAlertController

Christian Selig 22 Jul 18, 2022