Enhancing User Engagement: Utilizing Apple's Gauge for Dynamic Character Monitoring in SwiftUI

December 18, 2023 - 3 minute read
Gauge

Enhancing User Experience: Live Character Counting Circle

One lazy Sunday morning, while aimlessly scrolling through Twitter, an experience struck me: the circular animation that fills up as a user types a tweet.

The experience felt engaging; you type, and concurrently witness a live visualization of the characters being entered within a filling circle.

The Journey to Replicate

Inspired by this experience, I delved into reproducing it using Xcode. However, it proved more complex than anticipated initially.

Seeking guidance, I scoured articles on circle fill animations. While I successfully reproduced it using a custom view, adapting the code to suit my specific requirements and ensuring accessibility posed significant challenges.

Determined to simplify the process, I turned to the Apple Developer Documentation and stumbled upon Gauges, introduced in iOS 16.

The Gauge seemed tailor-made for my needs, as the documentation describes it: "A view that displays a value within a specified range."

Unraveling the User Story

To better grasp the scenario, I envisioned the user's journey while composing a tweet:

  • User inputs text
  • A visual cue appears as the character limit approaches, signaling 10 characters remaining
  • Upon reaching zero characters, a red circle displays negative numbers (0, -1, -2, -3, and so on)

Simplifying the Challenge

My approach aimed for simplicity. Forgoing a custom view, I relied on the built-in Gauge component.

Initially, I experimented within a Playground to develop the character logic before implementing it in my app.

Implementation

Key @State variables employed:

private let maximumChars: Int = 10
@State private var userInput: String = ""
@State private var value: Int = 0
@State private var isOverMaximumValue: Int?
@State private var tintColor: Color = .blue
@FocusState private var keyboardFocus: Bool

Method for character count calculation:

private func calculRemainingCharacters(
    input: String,
    maximumCharacters: Int
) {
    if input.count < maximumCharacters {
        value = input.count
        tintColor = .blue
        isOverMaximumValue = nil
    } else if input.count == maximumCharacters {
        tintColor = .red
        value = maximumCharacters
        isOverMaximumValue = 0
    } else {
        isOverMaximumValue = input.count - maximumCharacters
    }
}

Computed property to inform the user of excessive character count:

private var isZeroOrMore: String {
    guard let isOverMaximumValue else { return "" }
    return isOverMaximumValue == .zero ? "0" : "-\(isOverMaximumValue)"
}

The view setup:

List {
    VStack(alignment: .leading) {
        TextField("Write your thoughts", text: $userInput)
            .focused($keyboardFocus)
        Gauge(value: CGFloat(value), in: 0...CGFloat(maximumChars)) {
            Text(isZeroOrMore)
                .foregroundStyle(.red)
        }
        .tint(tintColor)
        .gaugeStyle(.accessoryCircularCapacity)
    }
}
.onChange(of: userInput) {
    calculateRemainingCharacters(input: userInput, maximumCharacters: maximumChars)
}

You can clone and compile for watch what's the result or watch the readme on the project's repository

Thank you for reading!

Feel free to reach out if you have any questions.

Explore more

Dexter Ramos
Programming, and reading novels
August 2, 2023 - 1 minute read

Day 1 Complete! 100 days of SwiftUI

Start of 100 days of swiftui

Hacking with swift image Day 1
October 8, 2023 - 4 minute read

Coding My Way to the App Store: A Self-Taught iOS Developer's Tale

My journey to develop my inaugural app on the App Store

Stellar To The Moon app icon
Want to get updated with the latest posts?

Subscribe