Limit width of wheel style picker on iOS

Hello,

I try to limit the width of a wheel style picker on iOS 15 using Xcode 13 beta5 in the code below. The drawing is correct, but the scroll areas of the elements overlap. So the toggle does not work and the the scrolling on the digits works with offset only. I have discovered this issue also on iOS 14.

Any idea how to fix this?

Matthias


import SwiftUI



struct ToggleButton: View {

    var key: String

    var systemImage: String?

    @Binding var isSelected: Bool

    

    var body: some View {

        Toggle(isOn: $isSelected, label: {

            if systemImage != nil {

                Label(key, systemImage: systemImage!)

            } else {

                Text(key)

            }

        }).toggleStyle(.button)

    }

}



struct DecimalPickerDigit: View {

    var pos: Int

    var height: CGFloat

    var value: Int

    var updateModel: (Int, Int)->Void

    

    var body: some View {

        Picker("", selection: Binding( get: { value },

                                       set: { val in updateModel(val, pos) })

        ) {

            ForEach(0 ..< 10, id: \.self) { i in

                Text("\(i)")

            }

        }

        .pickerStyle(.wheel)

        .labelsHidden()

        .frame(width: 20)

        .frame(idealHeight: height, maxHeight: .infinity)

        .clipped()

    }

}



struct ContentView: View {

    @State var isOn = false

    @State var intVal1 = 0

    @State var intVal2 = 0

    

    var body: some View {

        HStack {

            ToggleButton(key: "Toggle", isSelected: $isOn)

            DecimalPickerDigit(pos: 1, height: 100, value: intVal1, updateModel: { val, pos in intVal1 = val })

            DecimalPickerDigit(pos: 1, height: 100, value: intVal2, updateModel: { val, pos in intVal2 = val })

        }

    }

}

I do not know why this works, but an answer in an SO thread would work for you.

        Picker("", selection: Binding( get: { value },
                                       set: { val in updateModel(val, pos) })
        ) {
            ForEach(0 ..< 10, id: \.self) { i in
                Text("\(i)")
            }
        }
        .pickerStyle(.wheel)
        .labelsHidden()
        .frame(width: 20)
        .frame(idealHeight: height, maxHeight: .infinity)
        .clipped()
        .compositingGroup() //<-

Hello,

sorry for more late answers. I can reproduce the issue as well using iPhone 8 plus on simulator. See attached image.

Same issue with iOS 15.1, I am struggling for hours to fix it. none of the solutions work.

Yeah, same issue here... Works fine with .compositingGroup() in the canvas, and worked on physical iPhone running iOS 15.0, but after updating to 15.1 the touch overlays are back, and the initial solution not working anymore...

I submitted a feedback report for this (FB9764631)

Hello! im having the same problem now, with Xcode 13.2.1 and iOS 15. I have tried all possible solutions, but nothing works, i would be grateful if anyone can help me.

HStack(spacing: 8) { pickerA() .frame(minWidth: 0 ) .clipped() .compositingGroup() pickerB() .frame(minWidth: 0 ) .clipped() .compositingGroup() }.frame(width: 150)

I still have no solution for this. If you want to help then please fill a feedback report to Apple. There more requests they get for this, the more likely they solve it.

Please make sure you are on Xcode 13.2.1 and try again.

I tried with Xcode 13.2.1 and the behaviour did not change, so it's still an open issue

I'm running into the same issue now. It was working great with .clipped().compositingGroup() previously. It's in a part of the app that I don't regularly use, so I didn't notice until today that this broke with iOS15.1. I'm also on Xcode 13.2.1, same broken behaviour in the simulator and on a real device.

I have just decided to learn swift UI and convert one of my existing UIKit projects as a test. I have been struggling with this exact issue all day thinking I didn't understand the guides / tutorials. It sort of puts me off this 'new' framework a bit. Especially if the bug keeps being solved and then re-appears. Not something I would risk in one of my production applications for a client. Especially if this bug can not be easily (or at all) unit tested to see if its an issue.

I ran into the issue today and spent all night searching for workarounds but none worked. Then I find iOS 15.4 beta 3 and Xcode 13.3 beta 2 was released earlier this month. I'm going to upgrade my system tomorrow (it's late night here). Does anyone happen to know if the issue has been resolved on the latest release of iOS? Thanks.

Hello,

I just tried with iOS 15.4 beta 4 and the issue is still not resolved there.

I think to get heads-up from the Apple developers you must report an issue in their feedback assistant https://feedbackassistant.apple.com/welcome, writing here is not sufficient. The more people report this, the more likely we will get a fix.

Same trouble 😔

despite visual zones are obviously separated , padding zone is not , and the last to be display overrides the ones on the left

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

24

Disregard , I put the extension :

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

just before my pickerview struct declaration , and all my pickerviews are strictly working inside the stack they are in . Thank you so much 🙏🏻

Limit width of wheel style picker on iOS
 
 
Q