How do I make this Picker clip properly
Asked Answered
L

2

0

I create a set of side by side pickers in an HStack by calling the view below. The "control" area for each picker is much wider to the left of the picker than it should be. ".clipped()" is supposed to fix this, but it is not working. At some point when I was developing the code, it was working, but now I can't get it back. When I try to manipulate the pickers, I can move the rightmost one anywhere on the right 3 columns. The left column cannot be manipulated at all. What is going on here?

struct SinglePickerView: View {
    @Binding var note: Int
    let notes: [String]
    let width: CGFloat
   
    var body: some View {
        VStack {
            ZStack (alignment: .center) {
                RoundedRectangle(cornerRadius: 5)
                    .fill(Color(red: 192, green: 192, blue: 192))
                    .frame(width: width-10, height: 25)
                Text("\(notes[note])")
                .foregroundColor(.black)
            }

            Picker(selection: $note, label: Text("")) {
                ForEach(0 ..< 72) { index in
                    Text("\(self.notes[index])")
                        .foregroundColor(.white)
                        .tag(index)
               }
            }
            .labelsHidden()
            .frame(width: width)
            .clipped()
        }
    }
}
Lidialidice answered 20/8, 2020 at 2:55 Comment(0)
L
0

I finally found a reference to the real answer. The formulation below works, at least in iOS 13.6 and XCode 11.6.

Picker(selection: $note, label: Text("")) {
    ForEach(0 ..< 72) { index in
        Text("\(self.notes[index])")
            .frame(width: self.width)
            .foregroundColor(.white)
            .tag(index)
       }
}
.labelsHidden()
.frame(width: width)
.compositingGroup() 
.clipped()
Lidialidice answered 31/8, 2020 at 1:33 Comment(0)
S
0

Try to move clipped at parent container as below. Tested with Xcode 12 / iOS 14.

struct SinglePickerView: View {
    @Binding var note: Int
    let notes: [String]
    let width: CGFloat

    var body: some View {
        VStack {
            ZStack (alignment: .center) {
                RoundedRectangle(cornerRadius: 5)
                    .fill(Color(red: 192, green: 192, blue: 192))
                    .frame(width: width-10, height: 25)
                Text("\(notes[note])")
                .foregroundColor(.black)
            }

            Picker(selection: $note, label: Text("")) {
                ForEach(0 ..< notes.count, id: \.self) { index in
                    Text("\(self.notes[index])")
                        .foregroundColor(.white)
                        .tag(index)
               }
            }
            .labelsHidden()
        }
        .frame(width: width)
        .contentShape(Rectangle())
        .clipped()
    }
}

struct TestStackOfPickers: View {
    let notes = (1...10).map { String($0) }
    @State var note1 = 1
    @State var note2 = 5
    @State var note3 = 3

    var body: some View {
        HStack {
            SinglePickerView(note: $note1, notes: notes, width: 80).border(Color.red)
            SinglePickerView(note: $note2, notes: notes, width: 80).border(Color.red)
            SinglePickerView(note: $note3, notes: notes, width: 80).border(Color.red)
        }
    }
}
Selden answered 20/8, 2020 at 3:20 Comment(1)
Didn't seem to help. I'm on iOS 13.6 and XCode 11.6. I tried moving .clipped() out to the VStack as you suggest and also adding .contentShape() in either location. I do see that in the View preview, when it is stopped, blue boxes appear around the pickers exactly where I would expect to see them.Lidialidice
L
0

I finally found a reference to the real answer. The formulation below works, at least in iOS 13.6 and XCode 11.6.

Picker(selection: $note, label: Text("")) {
    ForEach(0 ..< 72) { index in
        Text("\(self.notes[index])")
            .frame(width: self.width)
            .foregroundColor(.white)
            .tag(index)
       }
}
.labelsHidden()
.frame(width: width)
.compositingGroup() 
.clipped()
Lidialidice answered 31/8, 2020 at 1:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.