iosswiftswiftuiswiftui-picker

Clickable area of SwiftUI Picker overlapping


I am currently trying to create a page with three adjacent Picker views inside of an HStack as seen below:

enter image description here

I made a CustomPicker view where I limit the frame to 90 x 240, and then use .compositingGroup() and .clipped() to make the selectable area of each picker not overlap.

CustomPicker.swift

import SwiftUI

struct CustomPicker: View {
    @Binding var selection: Int
    let pickerColor: Color
    
    var numbers: some View {
        ForEach(0...100, id: \.self) { num in
            Text("\(num)")
                .bold()
        }
    }
    
    var stroke: some View {
        RoundedRectangle(cornerRadius: 16)
            .stroke(lineWidth: 2)
    }
    
    var backgroundColor: some View {
        pickerColor
            .opacity(0.25)
    }
    
    var body: some View {
        Picker("Numbers", selection: $selection) {
            numbers
        }
        .frame(width: 90, height: 240)
        .compositingGroup()
        .clipped()
        .pickerStyle(.wheel)
        .overlay(stroke)
        .background(backgroundColor)
        .cornerRadius(16)
    }
}

ChoicePage.swift

struct ChoicePage: View {
    @State var choiceA: Int = 0
    @State var choiceB: Int = 0
    @State var choiceC: Int = 0
    
    var body: some View {
        HStack(spacing: 18) {
            CustomPicker(selection: $choiceA, pickerColor: .red)
            CustomPicker(selection: $choiceB, pickerColor: .green)
            CustomPicker(selection: $choiceC, pickerColor: .blue)
        }
    }
}

When testing both CustomPicker and ChoicePage in the preview canvas and simulator, it had worked perfectly fine, but when I tried to use it on my physical devices (iPhone 8 and iPhone 13, both on iOS 15.1) the clickable areas overlap. I have tried solutions from this post and this post, as well as many others, but nothing seems to be working for me.


Solution

  • adding this extension is working for me in 15.4

    extension UIPickerView {   
       open override var intrinsicContentSize: CGSize {     
          return CGSize(width: UIView.noIntrinsicMetric, height: super.intrinsicContentSize.height)} 
    }
    

    found at https://developer.apple.com/forums/thread/687986?answerId=706782022#706782022