CocoAttributedStringBuilder: Elegant and Easy AttributedStringBuilder in Swift

Overview

Swift Platforms CocoaPods Compatible Twitter Build Status

CocoAttributedStringBuilder: Elegant and Easy AttributedStringBuilder in Swift

Features

  • Use resultBuilder to create attributes
  • Support NSShadow Attributes
  • Support NSTextAttachment Attributes
  • Support NSParagraphStyle Attributes
  • Support NSParagraphStyle's NextTabs
  • Specify range for each attribute
  • Support if-statement on builders
  • Provide operator to define an attribute

Requirements

Platform Minimum Swift Version Installation Status
iOS 9.0+ 5.3 CocoaPods Tested

Installation

CocoaPods

CocoaPods is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate CocoAttributedStringBuilder into your Xcode project using CocoaPods, specify it in your Podfile:

pod 'CocoAttributedStringBuilder'

Sample

I have provided one sample project in the repository. To use it clone the repo, Source files for these are in the CocoAttributedStringBuilderExamples directory in project navigator. Have fun!

Usage

Using Coco is so easy, It is inspired by SwiftUI and the very useful PropertyWrapper @resultBuilder in swift.

You just need to annotate the functions or properties which return NSAttributedString to use Coco provided builders.

import CocoAttributedStringBuilder

@CocoAttributedStringBuilder
var builder: NSAttributedString { }

@CocoAttributedStringBuilder
func build() -> NSAttributedString { }

Create Your First CocoAttributedString

In order to create an AttributedString on Coco, you should use CocoString which takes a String and a builderBlock arguments.

String which was provided as an input argument is also available on the builderBlock to avoid outer variable or self capturing.

NSAttributedString { CocoString("Test Builder") { str in // attributes comes here } } ">
import CocoAttributedStringBuilder

@CocoAttributedStringBuilder
var builder: NSAttributedString {
    CocoString("Test Builder") { str in 
      // attributes comes here
    }
}

@CocoAttributedStringBuilder
func build() -> NSAttributedString {
    CocoString("Test Builder") { str in 
      // attributes comes here
    }
}

Attributes

Coco supports four kind of Attributes.

Each attribute is normally added to whole string, unless you specify the range of string you demand.

Coco is not responsible for handling invalid ranges, so be more careful on specifying the ranges.

Builders Description
CocoAttribute Provide a keyValue interface for NSAttributedString.Key
TextAttachment Provide a builder block for CocoAttachment which is an interface for NSTextAttachment
ParagrapghStyle Provide a builder block for CocoParagraphStyle which is an interface for NSParagraphStyle
TextTab Provide a builder block for CocoTextTab which is an interface for NSTextTab
CocoShadow Provide a builder block for CocoShadow which is an interface for NSShadow
import CocoAttributedStringBuilder

@CocoAttributedStringBuilder
func build() -> NSAttributedString {
    CocoString("Test Builder") { str in
        CocoAttribute.foregroundColor(.red)
            .on(str.startIndex..<str.firstIndex(of: "r")!)

        TextAttachment {
            CocoAttachment.bounds(.infinite)
        }
        .within(str.startIndex..<str.firstIndex(of: "r")!)
        
        ParagrapghStyle {
            CocoParagraphStyle.lineHeightMultiple(8)
            CocoParagraphStyle.lineSpacing(2.3)
            TextTab {
                CocoTextTab.tab(textAlignment: .left, location: 5)
                CocoTextTab.tab(textAlignment: .center, location: 5)
            }
        }
        .within { str.startIndex..<str.firstIndex(of: "h")! }

        Shadow {
            CocoShadow.shadowOffset(.init(width: 1.5, height: 1))
            CocoShadow.shadowColor(UIColor.black)
        }
        .within(str.startIndex..<str.firstIndex(of: "d")!)
    }
}

Using Meta-Type

Instead of Using Each Coco Enums to use its Attributes, you can use BuilderBlock with meta-type of Coco Enum provided for that Block.

import CocoAttributedStringBuilder

@CocoAttributedStringBuilder
func build() -> NSAttributedString {
CocoString("Test Builder") { str, a in
    a.foregroundColor(.red)
        .within(str.startIndex..<str.firstIndex(of: "r")!)

    TextAttachment { t in
        t.bounds(.infinite)
    }
}

Use Concrete Types

I recommend you to use either meta-type provides block or Coco Enums, but there is another way with one special condition. you can use each attribute Concrete type directly in each block if and only if that type is unique on that Enum.

On this example Bounds input argument is Unique in CocoCocoAttachment, so we can use its input concrete type to add as attribute, CGRect which is defined is consided as b.bounds(.infinite)

import CocoAttributedStringBuilder

@CocoAttributedStringBuilder
func build() -> NSAttributedString {
CocoString("Test Builder") { str, a in

    TextAttachment { t in
        CGRect.infinite
    }
}

Contributors

Feel free to share your ideas or any other problems. Pull requests are welcomed.

License

CocoAttributedStringBuilder is released under an MIT license. See LICENSE for more information.

You might also like...
An application focused on managing men's haircuts. It has never been so easy to keep the cut on time
An application focused on managing men's haircuts. It has never been so easy to keep the cut on time

An application focused on managing men's haircuts. It has never been so easy to keep the cut on time

BCSwiftTor - Opinionated pure Swift controller for Tor, including full support for Swift 5.5 and Swift Concurrency

BCSwiftTor Opinionated pure Swift controller for Tor, including full support for

 Zip - A Swift framework for zipping and unzipping files. Simple and quick to use. Built on top of minizip.
Zip - A Swift framework for zipping and unzipping files. Simple and quick to use. Built on top of minizip.

Zip A Swift framework for zipping and unzipping files. Simple and quick to use. Built on top of minizip. Usage Import Zip at the top of the Swift file

Useful Swift code samples, extensions, functionalities and scripts to cherry-pick and use in your projects

SwiftyPick 🦅 🍒 Useful Swift code samples, extensions, functionalities and scripts to cherry-pick and use in your projects. Purpose The idea behind t

A handy collection of Swift method and Tools to build project faster and more efficient.

SwifterKnife is a collection of Swift extension method and some tools that often use in develop project, with them you might build project faster and

TypeStyle is a handy app for iPhone and iPad that generates text using different styles and decorations. It is a native Swift iOS app.
TypeStyle is a handy app for iPhone and iPad that generates text using different styles and decorations. It is a native Swift iOS app.

TypeStyle TypeStyle is a handy app for iPhone and iPad that generates text using different styles and decorations. It is a native Swift iOS app. Featu

Async+ for Swift provides a simple chainable interface for your async and throwing code, similar to promises and futures
Async+ for Swift provides a simple chainable interface for your async and throwing code, similar to promises and futures

Async+ for Swift provides a simple chainable interface for your async and throwing code, similar to promises and futures. Have the best of both worlds

A lightweight extension to Swift's CollectionDifference, supporting moves in addition to removals and insertions, critical when updating interfaces and managing reference types.

DifferenceTracker is a lightweight extension to Swift's CollectionDifference. It defines moves in addition to removals and insertions, critical when updating interfaces and managing reference types.

Swift Markdown is a Swift package for parsing, building, editing, and analyzing Markdown documents.

Swift Markdown is a Swift package for parsing, building, editing, and analyzing Markdown documents.

Releases(0.3.1)
Owner
Kiarash Vosough
Kiarash Vosough
Swift-DocC is a documentation compiler for Swift frameworks and packages aimed at making it easy to write and publish great developer documentation.

Swift-DocC is a documentation compiler for Swift frameworks and packages aimed at making it easy to write and publish great developer docum

Apple 833 Jan 3, 2023
Easy CBOR encoding and decoding for iOS, macOS, tvOS and watchOS.

CBORCoding CBORCoding is a lightweight framework containing a coder pair for encoding and decoding Codable conforming types to and from CBOR document

Joe Newton 23 Nov 8, 2022
🗃 Powerful and easy to use Swift Query Builder for Vapor 3.

⚠️ This lib is DEPRECATED ⚠️ please use SwifQL with Bridges Quick Intro struct PublicUser: Codable { var name: String var petName: String

iMike 145 Sep 10, 2022
RandomKit is a Swift framework that makes random data generation simple and easy.

RandomKit is a Swift framework that makes random data generation simple and easy. Build Status Installation Compatibility Swift Package Manager CocoaP

Nikolai Vazquez 1.5k Dec 29, 2022
Easy way to detect iOS device properties, OS versions and work with screen sizes. Powered by Swift.

Easy way to detect device environment: Device model and version Screen resolution Interface orientation iOS version Battery state Environment Helps to

Anatoliy Voropay 582 Dec 25, 2022
Sovran-Swift: Small, efficient, easy. State Management for Swift

Sovran-Swift: Small, efficient, easy. State Management for Swift

Segment 5 Jan 3, 2023
SwiftRegressor - A linear regression tool that’s flexible and easy to use

SwiftRegressor - A linear regression tool that’s flexible and easy to use

null 3 Jul 10, 2022
Swift Date() made easy

Swift-Date-Extensions Swift Date() made easy! // Will return the wekkday in a st

Ricky Stone 0 Dec 28, 2021
Handling dimensional numbers with physical units in Swift made easy.

Dimensional arithmetics in Swift This package provides an easy and natural way of dealing with physical sizes. Performing complex arithmetics or unit

Niklas Nickel 1 May 27, 2022
Testable Combine Publishers - An easy, declarative way to unit test Combine Publishers in Swift

Testable Combine Publishers An easy, declarative way to unit test Combine Publishers in Swift About Combine Publishers are notoriously verbose to unit

Albert Bori 6 Sep 26, 2022