9

I've got the following view:

enter image description here

The Swift code looks like this:

struct TestView: View {
    let options = [" ", "1", "2", "3", "4", "5", "6"]
    @State var selectedIndex: Int = 0

    var body: some View {
        HStack(spacing: 0) {
            Text("One")

            Spacer()

            Picker(selection: $selectedIndex, label: Text(options[selectedIndex])) {
                ForEach(0 ..< options.count) {
                    Text(options[$0])
                }
            }
            .background(Color.red)
            .pickerStyle(MenuPickerStyle())
        }
        .padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16))
        .background(Color.yellow)
    }
}

When clicking on the red square, the Picker will be opened:

enter image description here

How can I extend the touch area of the red rectangle to also include the entire yellow area?

6
  • you only need to assign new selection value in your selectedIndex variable Commented Jan 3, 2021 at 11:49
  • What do you mean by 'open'? Is picker inside List ? Commented Jan 13, 2021 at 10:11
  • 1
    Can you add a more detailed / reproducible example? Commented Jan 13, 2021 at 10:38
  • I do not think that it is a good idea to show the Picker over the views. Instead expand the row like the one in iOS Calenadar. This stackoverflow.com/questions/64919284/… might help you. The question is mine and it works perfectly if your SuperView is not a List. Commented Jan 13, 2021 at 17:36
  • @pawello2222 I've updated the question, including screenshots and a copyable view Commented Jan 15, 2021 at 11:13

3 Answers 3

6

@DonMag's answer stopped working with iOS 15. Here's an updated answer that does work. Technically, it does not use Slider, the behavior is the same though. Instead a Menu is used.

struct PickerTestView: View {
    let options = [" ", "1", "2", "3", "4", "5", "6"]
    let optionNames = [" ", "One", "Two", "Three", "Four", "Five", "Six"]
    @State var selectedIndex: Int = 0

    var body: some View {
        ZStack {
            HStack(spacing: 0) {
                Text(optionNames[selectedIndex])
                Spacer()
            }
            .padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16))
            .background(Color.yellow)

            HStack(spacing: 0) {
                Menu {
                    ForEach(0 ..< options.count) {
                        let index = $0
                        Button("\(options[index])") {
                            selectedIndex = index
                        }
                    }
                } label: {
                    Label("", image: "")
                        .labelStyle(TitleOnlyLabelStyle())
                        .frame(maxWidth: .infinity)
                }
            }
        }
    }
}


struct PickerTestView_Previews: PreviewProvider {
    static var previews: some View {
        PickerTestView()
    }
}

Let's see when Apple decides to break this implementation.

Sign up to request clarification or add additional context in comments.

1 Comment

Perfect solution..!!
4
+100

Not sure this is exactly what you're after, but give it a try (initial view is a "blank" yellow bar):

import SwiftUI

struct PickerTestView: View {
    let options = [" ", "1", "2", "3", "4", "5", "6"]
    let optionNames = [" ", "One", "Two", "Three", "Four", "Five", "Six"]
    @State var selectedIndex: Int = 0

    var body: some View {
        ZStack {
            HStack(spacing: 0) {
                Text(optionNames[selectedIndex])
                Spacer()
            }
            .padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16))
            .background(Color.yellow)
            HStack(spacing: 0) {
                Picker(selection: $selectedIndex, label: Text(" ").frame(maxWidth: .infinity), content: {
                    ForEach(0 ..< options.count) {
                        Text(options[$0])
                    }
                })
                .pickerStyle(MenuPickerStyle())
            }
        }
    }

}

struct PickerTestView_Previews: PreviewProvider {
    static var previews: some View {
        PickerTestView()
    }
}

On launch:

enter image description here

Tap anywhere on the yellow bar:

enter image description here

After selecting "3":

enter image description here

1 Comment

The Picker shows the current selected option instead of the label in iOS15 so the picker in no longer invisible.
-1

A tricky solution is to use this


ZStack (alignment: .trailing) {
 ViewWhichYouWantToClick()

 Picker(selection: $pronouns, label: Text("")) {
       ForEach(themes,id:\.self) {
          Text($0)
       }
 }
 .opacity(0.02)
 .background(.clear)
 .accentColor(.white)
}
 

So the Picker is kinda invisible, but still clickable

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.