5

SWIFTUI I have a picker view(wheel type) and I clipped() its frame to half width of the screen, and from the UI you can see its half but the scrollable area is still actionable outside that frame. How can I remove that outer area to not be scrollable?

HStack(spacing: 0) {
    Picker(selection: self.$viewModel.selectedFrameworkIndex, label: Text("")) {
    ForEach(0 ..< viewModel.Categories.count) {
        Text(self.viewModel.Categories[$0])
            .foregroundColor((self.colorScheme == .dark) ? Color.white : Color.black)
         }
    }
    .frame(width: width / 2) // width is width of my screen
    .clipped() 
}
  • Works fine with Xcode 11.4 / iOS 13.4 with replicated code. Maybe the reason is somewhere else. What (where from) is `width`? Would you show more your code? – Asperi Jun 19 '20 at 04:02
  • I think you don't need to use `clipped` method as long as setting frame is correct. Nevertheless you want to force the touch event enabled in the frame area, just try to append `.contentShape(Rectangle())` right after `clipped`. It sets the hit testing area explicitly. – Kyokook Hwang Jun 20 '20 at 02:57

3 Answers3

8

Add .compositingGroup() after .clipped()

HStack(spacing: 0) {
Picker(selection: self.$viewModel.selectedFrameworkIndex, label: Text("")) {
ForEach(0 ..< viewModel.Categories.count) {
    Text(self.viewModel.Categories[$0])
        .foregroundColor((self.colorScheme == .dark) ? Color.white : Color.black)
     }
}
.frame(width: width / 2) // width is width of my screen
.clipped() 
.compositingGroup()  }    
Reed
  • 944
  • 7
  • 15
1

Adding this extension worked for me:

extension UIPickerView {
    open override var intrinsicContentSize: CGSize {
        return CGSize(width: UIView.noIntrinsicMetric, height: super.intrinsicContentSize.height)
    }
}
Timmy
  • 4,098
  • 2
  • 14
  • 34
Objective C
  • 21
  • 1
  • 5
0

Using .scaleEffect() works well for me. Please check Clickable area of SwiftUI Picker overlapping

Timmy
  • 4,098
  • 2
  • 14
  • 34
kutay
  • 51
  • 3