A package for building sentence-based UI in SwiftUI

Overview

SentenceUI

Screen Shot 2022-10-18 at 10 05 23 PM

SentenceUI is an SwiftUI package for building form interfaces with natural language.

Features

The goal for SentenceUI is to make it as easy as possible to implement Sentences in SwiftUI while still allowing for customization and extension. Features include:

  • 🔥 Declarative syntax for building Sentences using defined Fragment types and @State properties
  • 🎨 Fully customizable style using native content modifiers
  • 🏛 Built using native UI elements such as Text, TextField, Menu, and Picker
  • 🦄 Built-in block to handle special cases that arise when selected word forms need adjusted (Eg. "None" to "no")
  • 🧑‍🚀 Automatic spacing and wrapping between sentence fragments (Thanks to our only dependency, WrappingHStack!)

Install

Use Swift Package Manager and point to this repo!

Example

import SentenceUI

// Content modifiers used here will be applied to all fragments in a Sentence
struct BoldRed: SentenceStyleModifier {
    var fontSize: CGFloat = 50
    func body(content: Content) -> some View {
        content
            .tint(.red)
            .font(.system(size: fontSize, weight: .bold, design: .rounded))
    }
}

struct SentenceView: View {

    // Define state
    @State var size: String = "Large"
    @State var sweetAmt: String = "Light"
    @State var sweetnerType: String = "Sugar"
    @State var instructions: String = ""
    
    
    var body: some View {
        Sentence(
            fragments: [
            // Plain text fragment
            .text("I would like a"), 
            // Multichoice fragment allow users to select from an array of strings 
            .choice(ChoiceConfig(tag: "size", value: $size, options: ["Large", "Medium", "Small"], mask: nil)),
            .text("drink with"),
            .choice(ChoiceConfig(tag: "sweetAmt", value: $sweetAmt, options: ["Sweet", "Light", "None"], mask: nil)),
            .choice(ChoiceConfig(tag: "sweetType", value: $sweetnerType, options: ["Sugar", "Splenda", "Honey"], mask: nil))
        ],
            // Special cases block is where you can adjust word forms
            specialCases: { fragments in
                // Fragments to replace
                var replacements: [Fragment] = []
                
                // Get fragments by tag
                let amt = fragments.with(tag: "sweetAmt")!
                let sweetness = fragments.with(tag: "sweetType")!
                
                // Since fragments are enums you can handle special cases with case statement
                switch (amt, sweetness) {
                case (.choice(let a),.choice(_)):
                    // In this example, we want to prevent the sentence from reading "with None sugar"
                    // so we set the fragment mask to "No" so it displays sensibly
                    if a.value.wrappedValue == "None" {                        
                        replacements.append(.choice(ChoiceConfig(from: a, with: "No")))
                    }
                default:
                    break
                }
                
                // Always call modify with your replacements and return the result
                return fragments.modify(replacements)
        },
        style: BoldRed())
    }
}

About

This type of UI has been used successfully by apps like Beats by Dre (pre Apple Music) and Philz Coffee; both of which served as inspirations for this project. Natural language interfaces enjoy the advantage of feeling instantly familiar to users. If you can read, you already know how to use it. They're fun to develop with, too, because you have to step into the user's story in order to compose the sentences about what they're doing inside of your application.

This is the updated SwiftUI version of my previous SentenceKit project. More thoughts on this blog post.

You might also like...
Package that extends Combine with some useful APIs

CombineExpanded Package that extends Combine with some useful APIs. New API: then shareReplay Future.deferred then Wait for completion of self, then f

FlutterNativeDragAndDrop - A package that allows you to add native drag and drop support into your flutter app
FlutterNativeDragAndDrop - A package that allows you to add native drag and drop support into your flutter app

native_drag_n_drop A package that allows you to add native drag and drop support

An IPFS client/api Swift Package, with the ability to add and pin any data on iOS/iPadOS/macOS

An IPFS client/api Swift Package, with the ability to add and pin any data on iOS/iPadOS/macOS. Originally bundled with GraniteUI, pulled out for independant use by any party.

WebDomHandling - A Swift Package for handling JavaScript code between WebKit and Swift implemented by WebKit

WebDomHandling A Swift Package for handling JavaScript code between WebKit and S

SafeDecoder - a swift package that set defaults when Codable fails to decode a field

SafeDecoder is a swift package that set defaults when Codable fails to decode a field. SafeDecoder supports configurable default values, See SafeDecoder.Configuration.

Trigonometry - A small package to calculate values in an right angled triangle

Trigonometry - A small package to calculate values in an right angled triangle

This is a Swift Package bundling different Train APIs into one simple Swift interface.

This is a Swift Package bundling different Train APIs into one simple Swift interface.

GraphQL based Jetpack Compose, Wear Compose and SwiftUI Kotlin Multiplatform sample
GraphQL based Jetpack Compose, Wear Compose and SwiftUI Kotlin Multiplatform sample

GraphQL based Jetpack Compose, Wear Compose and SwiftUI Kotlin Multiplatform sample

DBZ-Legends - A SwiftUI based app for all the DBZ peeps out there
DBZ-Legends - A SwiftUI based app for all the DBZ peeps out there

DBZ-Legends Just a simple UI based app for all the DBZ fans. You can tap on the

Releases(v0.5.0)
Owner
Ricky
Ricky
Yummies is my first attempt at building a native iOS app using Swift and SwiftUI

Yummies is my first attempt at building a native iOS app using Swift and SwiftUI. A recipe browser where you can pin your favorite ones. Powered by Edamam Recipe Search API.

Yavor Radulov 2 Aug 27, 2022
This repository hosts the PushwooshGeozones iOS SDK as an XCFramework based Swift Package.

This repository hosts the PushwooshGeozones iOS SDK as an XCFramework based Swift Package. Use this repository's Swift Package in Xcode 12+

Pushwoosh 2 Nov 23, 2021
A Kotlin multiplatform library for building dynamic server-driven UI

Component Box · A Kotlin multiplatform library for building dynamic server-driven UI. Material Component-Based Interoperable Dynamic What You See Is W

Dropbox 216 Dec 31, 2022
A nano-sized weather station based on a Raspberry Pi with an API, iOS & Mac Catalyst app, and sensor-based automations.

Nanotool A nano-sized weather station based on a Raspberry Pi with an API, iOS & Mac Catalyst app, and sensor-based automations. Descriere Vremea este

CMD 3 Aug 18, 2022
A macOS application for accessing the output of the SimpleAnalytics package on the desktop.

The SimpleAnalytics package allows you to collect data user interaction analytic data in iOS and macOS applications. This SimpleAnalytics Reader app project allows you to more easily make sense of that collected data by displaying it on your Mac.

Dennis Birch 10 Dec 22, 2022
Flutter package for detecting NSFW images and videos using native implementation

Flutter NSFW 1- Download, tflite modle and put it in assets folder 2 - Add the path of the tfliet to pubspec.yaml 3 - Read the file using path_provide

Syed Ahsan Ali 8 Oct 16, 2022
React Native package for interacting with HomeKit devices

React Native package for interacting with HomeKit devices

Ibrahim Berat Kaya 4 Dec 24, 2021
A corresponding package to RxKotlin Plus, but for Swift and iOS

A corresponding package to RxKotlin Plus, but for Swift and iOS

Lightning Kite 0 Dec 15, 2021
A simple protocol package that does nothing

HasResult A simple protocol package that does nothing. The HasResult protocol has a simple result property and a ResultType associated type. This is m

François Lamboley 0 Nov 6, 2021
A Swift package for encoding and decoding Swift Symbol Graph files.

SymbolKit The specification and reference model for the Symbol Graph File Format. A Symbol Graph models a module, also known in various programming la

Apple 141 Dec 9, 2022