Kngw Kngw
Kngw Kngw

Reputation: 61

How to Display Both Clear Button and Unit Label in UITextField Like in Apple Health App?

I’m struggling to replicate the behavior of a TextField or UITextField similar to the one shown in the attached image. The image is from the Apple Health app’s weight input section.

enter image description here

What I’m trying to achieve:

•   Display a placeholder.
•   Show the clear button (.whileEditing).
•   Always display a unit label (e.g., “kg”) next to the value (.always).

However, when I try to implement this with the following code:

    let label = UILabel()
    label.text = "kg"
    textField?.clearButtonMode = .whileEditing
    textField?.rightView = label
    textField?.rightViewMode = .always

The issue is that when the rightView (the unit label) appears, the clear button disappears, so I can’t have both at the same time. I’m curious if there’s a native approach that Apple uses to achieve this type of UX.

Any insights or solutions would be appreciated.

I’m aware that a similar question was asked over 10 years ago, but since SwiftUI didn’t exist back then, I’m asking again to see if there are any new solutions available.

Upvotes: 0

Views: 76

Answers (1)

Try this simple approach using a selectedId to determine which Item is to be edited. Adjust the code UI and logic, to suit your needs.

struct Item: Identifiable {
    let id = UUID()
    var title: String
    var value: Double?
}


struct ContentView: View {
    @State private var items = [Item(title: "Height"), Item(title: "Weight"), Item(title: "Blood Type")]

    @State private var selectedId: UUID?
    
    var body: some View {
        List($items) { $item in
            HStack {
                Text(item.title).foregroundStyle(.black)
                Spacer()
                if selectedId == item.id {
                    TextField(item.title, value: $item.value, format: .number)
                        .keyboardType(.numberPad)
                        .frame(width: 88)
                    Text(" Kg")
                    Image(systemName: "x.circle.fill")
                        .foregroundStyle(.gray)
                        .onTapGesture {
                            item.value = nil
                        }
                } else {
                    Text(item.value == nil ? "Add" : "\(item.value!) Kg")
                        .onTapGesture {
                            selectedId = item.id
                        }
                }
            }
            .foregroundStyle(.blue)
        }
    }
}

Upvotes: 0

Related Questions