2

I would like to limit the tappable area of the picker in a form to only it's visible area of text (i.e. black rectangle in the picture below). Currently whole row can be tappable.

Screen capture of the program

Here is the code:

import SwiftUI

struct ContentView: View {
    @State var rate: String = ""
    @State var units = ["mL/day","mL/hour"]
    @State var unit: Int = 0
    var body: some View {
        NavigationView{
            Form{
                HStack{
                    Text("Rate")
                    TextField("0", text: $rate)
                    Picker(selection: $unit, label: Text(""), content: {
                        ForEach(0..<units.count, content: { unit in
                            Text(units[unit])
                        })
                    })
                    .frame(width: 100.0)
                    .compositingGroup()
                    .clipped()
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

I read through this question and try to add .clipped() and .compositingGroup() but seems not useful.

1 Answers1

1

You are going to have to redesign the UI a bit. I would recommend this:

struct ContentView: View {
    @State var rate: String = ""
    @State var units = ["mL/day","mL/hour"]
    @State var unit: Int = 0
    var body: some View {
        NavigationView{
            Form{
                Section(header: Text("Rate")) { // Do This
                    HStack{
                        TextField("0", text: $rate)
                            .background(Color.red)
                        Picker(selection: $unit, label: Text(""), content: {
                            ForEach(0..<units.count, content: { unit in
                                Text(units[unit])
                            })
                        })
                        .frame(width: 100)
                        .clipped()
                        .background(Color.green)
                    }
                }
            }
        }
    }
}

I made colored backgrounds for each of the subviews. The issue is not that the whole row is selectable. It is that when you have a Picker() in the row, any view that is not itself selectable, in this case the Text() triggers the Picker(). If you use your code and put a colored background behind the text, you will see what happens. If you tap on the Picker() it triggers. If you tap on the TextField() you get an insertion point there. But if you tap on the Text() it triggers the Picker(). The .compositingGroup doesn't affect this behavior at all.

I have this exact design in an app, and the solution is to put the text into Section with a header, or put the Text() in the row above.

Yrb
  • 8,103
  • 2
  • 14
  • 44