3

I'm trying to create a component that's basically two SwiftUI pickers right next to eachother, like this: enter image description here

Right now its just a super simple implementation:

@State var hourSelection = 0
@State var daySelection = 0

var days = [Int](0 ..< 30)
var hours = [Int](0 ..< 30)

...

GeometryReader { proxy in
  HStack(spacing: 0) {
    Picker(selection: self.$daySelection, label: Text("")) {
      ForEach(0 ..< self.days.count) { index in
        Text("\(self.days[index]) d").tag(index)
      }
    }
    .pickerStyle(.wheel)
    .frame(width: proxy.size.width / 2, height: proxy.size.height, alignment: .leading)

    Picker(selection: self.$hourSelection, label: Text("")) {
      ForEach(0 ..< self.hours.count) { index in
        Text("\(self.hours[index]) h").tag(index)
      }
    }
    .pickerStyle(.wheel)
    .frame(width: proxy.size.width / 2, height: proxy.size.height, alignment: .trailing)
  }
}

Trying to use the picker on the left simple uses the picker on the right. In other words, they overlap. How can I fix this using SwiftUI? No other solutions on Stack Overflow have worked for me.

I have looked at Pickers are overlapping in ios 15 preventing some of them to be scrolled but the accepted solution does not work for me.

I tried using .compositingGroup() followed by .clipped() after the .frame(), but this has not worked, nor has applying .mask(Rectangle()) to the parent container.

Update: Even with the iOS 16 update and new XCode Beta, the problem remains the same.

Nicolas Gimelli
  • 695
  • 7
  • 19
  • Does this answer your question? [Pickers are overlapping in ios 15 preventing some of them to be scrolled](https://stackoverflow.com/questions/69365738/pickers-are-overlapping-in-ios-15-preventing-some-of-them-to-be-scrolled) – Yrb May 25 '22 at 00:21
  • No, unfortunately I do not believe that solution still works. – Nicolas Gimelli May 25 '22 at 01:44

3 Answers3

2

Another possible variant - just to make underlying UIPickerView (because it is it responsible for the issue) to be compressible:

Tested with Xcode 13.4 / iOS 15.5

demo

extension UIPickerView {
    override open func didMoveToSuperview() {
        super.didMoveToSuperview()
        self.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
    }
}

Test module on GitHub

Asperi
  • 228,894
  • 20
  • 464
  • 690
0

This worked for me:

extension UIPickerView {
    open override var intrinsicContentSize: CGSize {
        return CGSize(width: UIView.noIntrinsicMetric, height: super.intrinsicContentSize.height)
    }
}
Asperi
  • 228,894
  • 20
  • 464
  • 690
Objective C
  • 21
  • 1
  • 5
0

you could try adding .clipped(), after each .frame(width: proxy...). Works for me on macos 12.5, using Xcode 13.3, targets ios-15 macCatalyst 12.3, tested on real devices only.