当前位置:   article > 正文

[SwiftUI]HStack中放多个Picker不平分区域以及Picker在父视图之外还能滚动问题的修复_swiftui hstack 平分

swiftui hstack 平分

问题一:HStack中多个Picker不平分区域

一个自定义日期选择器,代码如下。在iOS16.12上一切正常,但在iOS15.8就出现问题。

  1. HStack {
  2. let pickerLabelOffset: CGFloat = 25
  3. ZStack {
  4. Picker(selection: $selectedMonth, label: Text("Month")) {
  5. ForEach(1...12, id: \.self) { month in
  6. Text(String(format: "%02d", month))
  7. .tag(month)
  8. .font(.regular(23))
  9. }
  10. }
  11. .pickerStyle(InlinePickerStyle())
  12. .background(Color.red)
  13. .clipped()
  14. Text("M")
  15. .font(.regular(20))
  16. .offset(x: pickerLabelOffset)
  17. }
  18. ZStack {
  19. Picker(selection: $selectedDay, label: Text("Day")) {
  20. ForEach(1...31, id: \.self) { day in
  21. Text(String(format: "%02d", day))
  22. .tag(day)
  23. .font(.regular(23))
  24. }
  25. }
  26. .pickerStyle(InlinePickerStyle())
  27. .background(Color.green)
  28. .clipped()
  29. Text("D")
  30. .font(.regular(20))
  31. .offset(x: pickerLabelOffset)
  32. }
  33. ZStack {
  34. Picker(selection: $selectedYear,label: Text("Year")) {
  35. ForEach(2024..<2034, id: \.self) { year in
  36. let y = "\(year - 2000)"
  37. Text(y)
  38. .tag(year)
  39. .font(.regular(23))
  40. }
  41. }
  42. .pickerStyle(InlinePickerStyle())
  43. .background(Color.yellow)
  44. .clipped()
  45. Text("Y")
  46. .font(.regular(20))
  47. .offset(x: pickerLabelOffset)
  48. }
  49. }
  50. .frame(height: 286)
  51. .background(Color.white)
  52. .cornerRadius(8)
  53. .padding(.horizontal, 35)

正常效果:

异常效果:




 

修复:给Picker限制宽度

代码如下,给Picker限制宽度后,虽然修复了上面区域平分问题,但又产生了一个新问题(下面的问题二)。

  1. HStack {
  2. let pickerLabelOffset: CGFloat = 25
  3. Spacer()
  4. ZStack {
  5. Picker(selection: $selectedMonth, label: Text("Month")) {
  6. ForEach(1...12, id: \.self) { month in
  7. Text(String(format: "%02d", month))
  8. .tag(month)
  9. .font(.regular(23))
  10. }
  11. }
  12. .pickerStyle(InlinePickerStyle())
  13. .frame(width: 88)
  14. .background(Color.red)
  15. .clipped()
  16. Text("M")
  17. .font(.regular(20))
  18. .offset(x: pickerLabelOffset)
  19. }
  20. Spacer()
  21. ZStack {
  22. Picker(selection: $selectedDay, label: Text("Day")) {
  23. ForEach(1...31, id: \.self) { day in
  24. Text(String(format: "%02d", day))
  25. .tag(day)
  26. .font(.regular(23))
  27. }
  28. }
  29. .pickerStyle(InlinePickerStyle())
  30. .frame(width: 88)
  31. .background(Color.green)
  32. .clipped()
  33. Text("D")
  34. .font(.regular(20))
  35. .offset(x: pickerLabelOffset)
  36. }
  37. Spacer()
  38. ZStack {
  39. Picker(selection: $selectedYear,label: Text("Year")) {
  40. ForEach(2024..<2034, id: \.self) { year in
  41. let y = "\(year - 2000)"
  42. Text(y)
  43. .tag(year)
  44. .font(.regular(23))
  45. }
  46. }
  47. .pickerStyle(InlinePickerStyle())
  48. .frame(width: 88)
  49. .background(Color.yellow)
  50. .clipped()
  51. Text("Y")
  52. .font(.regular(20))
  53. .offset(x: pickerLabelOffset)
  54. }
  55. Spacer()
  56. }
  57. .frame(height: 286)
  58. .background(Color.white)
  59. .cornerRadius(8)
  60. .padding(.horizontal, 35)

示意图:

问题二:Picker在父视图之外还能滚动

如上图,想要滚动左边第一个Picker实际却滚动了中间第二个Picker,想要滚动第二个picker实际却滚动了第三个picker。问题就是,Picker在父视图ZStack的边框之外还能响应滚动事件。

这个问题,网上推荐给Picker添加.clipped()和.compositingGroup()修饰,以及给ZStack添加.contentShape(Rectangle()),但这些方式都没让我的问题得到解决。

修复方式一:能同时修复问题一和问题二

在stackoverflow找到了另一种解决方案,能完美解决我这里的问题。这种方式能同时修复问题一和问题二,问题一的源码不用修改,直接添加下方的扩展就解决问题了。

https://stackoverflow.com/questions/62462747/swiftui-picker-view-touch-scroll-able-area-is-still-out-of-frame-even-after-us

  1. import Foundation
  2. // 解决Picker在父视图之外还能滚动问题
  3. extension UIPickerView {
  4. open override var intrinsicContentSize: CGSize {
  5. return CGSize(width: UIView.noIntrinsicMetric, height: super.intrinsicContentSize.height)
  6. }
  7. }

示意图:

修复方式二:将Picker放到ScrollView或者Form之内

将Picker放到ScrollView或者Form之内,这样它们将在隔离的滚动视图中,可能减少触摸事件的冲突。

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号