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

Michie Ang
Roaming around at dubdub.Space 😊
June 13, 2022 - 1 minute read

Welcome to dubdub space!

dubdub space is a space for us to share about our learnings and journeys as an Apple App Developer.

Dexter Ramos
Programming, and reading novels
September 9, 2023 - 4 minute read

iOS Development, Swift: How to receive message from a web page

This article will demonstrate how an iOS app can receive message from a web page. This is in contrast to receiving message or data from backend.

Web page message handling article cover
Want to get updated with the latest posts?

Subscribe