_Text is a simple augmentation to SwiftUI that makes styling easier

Overview

_Text

_Text is a simple augmentation to SwiftUI that makes styling easier. By utilizing the environment it is possible to apply text modifiers to any views children text. The goal of this library is to make it as seamless as possible to adopt _Text in your own projects.

Things of note:

  • This library comes with 2 packages, _Text and _TextCore. The namesake package typealiases Text to _Text and exports core. If you would prefer not to do that, import _TextCore instead.
  • This library extends a lot of the SwiftUI interfaces to provide seamless interop where Text would be used. We attempt to cover all of the interfaces.
  • _Text reflects the exact same API as Text, and the APIs function the same. However, the only way for our indirect styles to be applied is if our text object is rendered in a View. This is due to the reliance on Environment in order to work.
  • You can even concatenate _Text with Text!

If you are using this library & also other SwiftUI components that accept a Text property, you may want create shims for the components intitializers or you can utilize _Text._text to get the inner SwiftUI Text container.

Examples

There are a view ways to utilize _Text, here are a few examples:

Basic

Note the way we are importing here. This is so our Text can take over for the SwiftUI Text, otherwise we would get amigious type warnings or have to use _Text everywhere.

import SwiftUI
import struct _Text.Text

struct ContentView: View {
  var body: some View {
    VStack {
      Text("Oh wow, I am BOLD!")

      Text("Oh wow, I am BOLD and WIDE!")
        .text(.kerning(2))
        
      Text("Oh wow, I am ITALIC, BOLD, and WIDE!")
        .text(.kerning(2))
        .text(.italic())
    }
    .text(.bold())
  }
}

Closure

Closure stylings behave differently from the way text(_:) works. This technique for applying style works most similarly to how the various styles in SwiftUI function, like listStyle(_:) and buttonStyle(_:).

You get the underlying Text instance that needs styling in a closure, then return it when finished.

import SwiftUI
import struct _Text.Text

struct ContentView: View {
  var body: some View {
    VStack {
      Text("Oh wow, I am ITALIC, BOLD, and WIDE!")
    }
    .textStyle {
      $0.italic().bold().kerning(2) // implicit return! nice.
    }
  }
}

Styles

Styles work exactly like they do in other SwiftUI components. You first conform to the protocol TextStyle, then implement your desired styling. The styling aspect is very similar to how the closure works, but instead is embedded in a struct. The benefit of that is you can now customize the style in a more controller way, or even listen to Environment and change how your text gets styled.

SwiftUI.Text { text.font(.largeTitle).bold().kerning(2) } } extension TextStyle where Self == SubheaderTextStyle { static var subheader: Self { .init() } } struct SubheaderTextStyle: TextStyle { func applyStyle(_ text: SwiftUI.Text) -> SwiftUI.Text { text.italic().foregroundColor(.secondary) } }">
import SwiftUI
import struct _Text.Text

struct ContentView: View {
  var body: some View {
    VStack {
      Text("Oh wow, I am ITALIC, BOLD, and WIDE!")
      Text("Sub header")
        .textStyle(.subheader)
    }
    .textStyle(.header)
  }
}

extension TextStyle where Self == HeaderTextStyle {
  static var header: Self { .init() }
}

struct HeaderTextStyle: TextStyle {
  func applyStyle(_ text: SwiftUI.Text) -> SwiftUI.Text {
    text.font(.largeTitle).bold().kerning(2)
  }
}

extension TextStyle where Self == SubheaderTextStyle {
  static var subheader: Self { .init() }
}

struct SubheaderTextStyle: TextStyle {
  func applyStyle(_ text: SwiftUI.Text) -> SwiftUI.Text {
    text.italic().foregroundColor(.secondary)
  }
}

3rd Party

When interacting with external libraries that may require we pass SwiftUI's Text, we have two ways of handling this, but both have the unfortunate side effect of our indirect styles not being applied. The preferred workaround is using a manual content closure instead of passing Text when possible.

Use eraseToText()

import SwiftUI
import _Text
import NeatButton

struct ContentView: View {
 var body: some View {
   VStack {
     // This library accepts normal SwiftUI `Text`, not `_Text`.
     NeatButton(
       Text("Oh wow, I am ITALIC, BOLD, and WIDE!").eraseToText()
     ) {
       // do something...
     }
   }
   .textStyle {
     $0.italic().bold().kerning(2) // implicit return! nice.
   }
 }
}

Create shims

If you are going to be interacting with a library often, it is probably easier to create a shim.

import SwiftUI
import _Text
import NeatButton

extension NeatButton {
   init(_ text: _Text, action: () -> Void) {
     self.init(text.eraseToText(), action: action)
   }
}

struct ContentView: View {
 var body: some View {
   VStack {
     // Now _Text is erased to Text when we use it.
     NeatButton(Text("Oh wow, I am ITALIC, BOLD, and WIDE!")) {
       // do something...
     }
   }
   .textStyle {
     $0.italic().bold().kerning(2) // implicit return! nice.
   }
 }
}

License

This library is released under the MIT license.

You might also like...
GRE3000 - Simple GRE 3000 words app for Chinese
GRE3000 - Simple GRE 3000 words app for Chinese

GRE3000 Simple GRE 3000 words app for Chinese Usage Tap Left half Screen for pre

Like a SwiftUI ViewBuilder, but for Text
Like a SwiftUI ViewBuilder, but for Text

TextBuilder Introduction Text composition in SwiftUI can often be cumbersome, especially when there's logic affecting its format and content. TextBuil

Markdown in SwiftUI, and some other interesting components.
Markdown in SwiftUI, and some other interesting components.

RoomTime RoomTime is a bundle of tools developed in my app RoomTime Lite. ( šŸ˜Š RoomTime Lite is still in development) Features TextArea AutoWrap Markd

A lightning fast, native SwiftUI scratchpad/text editor.

Sedit A lightning fast, native SwiftUI scratchpad/text editor. Sedit (Swift Edit, as in the language and as in fast) is a lightning fast basic text ed

Easily show RichText(html) in SwiftUI
Easily show RichText(html) in SwiftUI

RichText LightMode DarkMode Code import SwiftUI

Generate SwiftUI Text or AttributedString from markdown strings with custom style names.
Generate SwiftUI Text or AttributedString from markdown strings with custom style names.

iOS 15.0 / macOS 12.0 / tvOS 15.0 / watchOS 8.0 StyledMarkdown is a mini library that lets you define custom styles in code and use them in your local

Render Markdown text in SwiftUI, preview based on the Marked implementation
Render Markdown text in SwiftUI, preview based on the Marked implementation

Markdown Render Markdown text in SwiftUI. It is a preview based on the Marked implementation. swiftui-markdown.mov Installation You can add MarkdownUI

AttributedText is a Swift Āµpackage that provides NSAttributedString rendering in SwiftUI by wrapping either an NSTextView or a UITextView depending on the platform.
AttributedText is a Swift Āµpackage that provides NSAttributedString rendering in SwiftUI by wrapping either an NSTextView or a UITextView depending on the platform.

AttributedText AttributedText is a Swift Āµpackage that provides NSAttributedString rendering in SwiftUI by wrapping either an NSTextView or a UITextVi

Rendering Markdown text natively in SwiftUI.
Rendering Markdown text natively in SwiftUI.

MarkdownView MarkdownView is a Swift Package for rendering Markdown text natively in SwiftUI. Thanks to apple/swift-markdown, it can fully compliant w

Releases(0.1.0)
Owner
Eric Lewis
Developer & Father. Feel free to reach out on twitter if I don't get back to you here.
Eric Lewis
AttributedString Markdown initializer with custom styling

AttributedString Markdown initializer with custom styling AttributedString in iOS 15 and macOS 12 comes with a Markdown initializer. But: There is no

Frank Rausch 41 Dec 19, 2022
An easier way to compose attributed strings

TextAttributes makes it easy to compose attributed strings. let attrs = TextAttributes() .font(name: "HelveticaNeue", size: 16) .foregroundCol

Damien 2.2k Dec 31, 2022
A simple and customizable Markdown Parser for Swift

MarkdownKit MarkdownKit is a customizable and extensible Markdown parser for iOS and macOS. It supports many of the standard Markdown elements through

Bruno Oliveira 687 Dec 18, 2022
RichEditorView is a simple, modular, drop-in UIView subclass for Rich Text Editing.

RichEditorView RichEditorView is a simple, modular, drop-in UIView subclass for Rich Text Editing. Written in Swift 4 Supports iOS 8+ through Cocoapod

Caesar Wirth 1.8k Dec 24, 2022
A simple library for building attributed strings, for a more civilized age.

Veneer A simple library for building attributed strings, for a more civilized age. Veneer was created to make creating attributed strings easier to re

Wess Cope 26 Dec 27, 2022
Heimdall is a wrapper around the Security framework for simple encryption/decryption operations.

Heimdall In Norse mythology, Heimdall is the gatekeeper of Bifrƶst, the rainbow road connecting Midgard, realm of the humans, to Asgard, the realm of

Henri Normak 393 Nov 23, 2022
Swift String Validator. Simple lib for ios to validate string and UITextFields text for some criterias

Swift String validator About Library for easy and fastest string validation based on сciterias. Instalation KKStringValidator is available through Coc

Kostya 17 Dec 21, 2019
A simple library that provides standard Unicode emoji support across all platforms

Twitter Emoji (Twemoji) A simple library that provides standard Unicode emoji support across all platforms. Twemoji v13.1 adheres to the Unicode 13.0

Twitter 15k Jan 8, 2023
A simple Cron Parser with Swift

A simplified cron parser Requirements Swift 5.5 Command line tools How to Run Cr

null 0 Dec 21, 2021
Simple, keyboard-first, markdown note-taking for MacOS

QuickDown Simple, keyboard-first, markdown note-taking for MacOS Main Features Global Hotkey: āŒ˜-āŒ„-N Save Note: āŒ˜-S Launch on Login (Optional) Addition

Alexis Rondeau 50 Nov 29, 2022