有人知道如何更改 SwiftUI 中默认 DatePicker 的大小吗?我一直在尝试提供一个自定义框架来调整 DatePicker 的大小,但我看不到预期的结果。
这是我尝试过的:
DatePicker("", selection: $currentDate, displayedComponents: .hourAndMinute)
.labelsHidden()
.frame(width: 150, height: 80, alignment: .center)
只需将其夹在末端即可,如下所示...
DatePicker("", selection: $currentDate, displayedComponents: .hourAndMinute)
.labelsHidden()
.frame(width: 150, height: 80, alignment: .center)
.clipped()
您可以使用变换效果更改其大小,此示例会将 DatePicker 大小减小为其默认大小的 0.8 只需将此修改器添加到选择器
DatePicker(......).transformEffect(.init(scaleX: 0.8, y: 0.8))
我在日期选择器后面添加了.scaleEffect(),现在我可以实现尺寸缩放...
虽然改变原生
DatePicker
的大小仍然是不可能的,但构建自定义的已经变得更容易了。在 iOS 16.4 中,Apple 引入了 .presentationCompactAdaptation
,这使得可以像原生 DatePicker
一样弹出日期弹出框。这样,就不再需要对原始答案进行黑客攻击了。
以下代码使解决方案尽可能向下兼容。
.popover(isPresented: $showPicker) {
if #available(iOS 16.4, *) {
DatePicker("", selection: $date, displayedComponents: [.date])
.datePickerStyle(.graphical)
.frame(width: 320)
.presentationCompactAdaptation(.popover)
} else if #available(iOS 16.0, *) {
DatePicker("", selection: $date, displayedComponents: [.date])
.datePickerStyle(.graphical)
.frame(width: 320)
.presentationDetents([.medium])
} else {
DatePicker("", selection: $date, displayedComponents: [.date])
.datePickerStyle(.graphical)
.frame(width: 320)
}
}
虽然这并不能直接解决更改 SwiftUI DatePicker 大小的问题,但对于必须使用 SwiftUI 的人来说,它仍然可能会感兴趣
DatePicker
。
我发现在 SwiftUI 中调整
DatePicker
大小的唯一方法是使用 .scaleEffect()
修饰符。所以我的想法是创建我自己的 UI,将点击传递到它所覆盖的 DatePicker,然后显示弹出窗口。
为了使视图完全可点击,必须缩放
DatePicker
以覆盖整个宽度。为了动态计算 DatePicker
和覆盖 UI 之间的比例因子,我使用了两个 DatePicker,将其放置在覆盖 UI 后面 - 两个读取本机宽度,一个用于调整大小。
下面的实现仅在 X 轴上缩放,因为这已经实现了我所需要的。
struct ScalingDatePicker: View {
@Binding var selection: Date
@State var datepickerSize: CGSize = .zero
let displayComponents: DatePicker.Components = [.date]
static let formatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "dd.MM.yyyy"
return formatter
}()
var body: some View {
ZStack(alignment: .leading) {
// Hidden DatePicker to grab the Size for calculations
DatePicker("", selection: $selection, displayedComponents: displayComponents)
.background(
GeometryReader { geo in
Color.clear.onAppear {
datepickerSize = geo.size
}
}
)
.allowsHitTesting(false)
.fixedSize()
.opacity(0)
GeometryReader { geo in
DatePicker("", selection: $selection, displayedComponents: displayComponents)
.scaleEffect(
x: geo.size.width/datepickerSize.width,
anchor: .topLeading
)
.labelsHidden()
.frame(maxWidth: .infinity, alignment: .leading)
.padding(6)
}
Text(Self.formatter.string(from: selection))
.frame(maxWidth: .infinity, alignment: .leading)
.padding(12)
.background(Color.white)
.allowsHitTesting(false)
// .opacity(0.5) // -> use this to see the scaling effect in action
.overlay(
RoundedRectangle(cornerRadius: 5)
.strokeBorder(.black)
)
}
.fixedSize(horizontal: false, vertical: true)
}
}
这个解决方案在我的情况下不起作用,因为我无法将宽度传递到
.frame()
,因为我的视图层次结构是如何实现的(滚动视图等)
或者,我可以在 DatePicker 上创建一个扩展并覆盖其
intrinsicContentSize
var 以返回一个 CGSize,其宽度为 UIView.noIntrinsicMetric
。然后我可以使用 .fixedSize(horizontal: false, vertical: true)
修改器来调整日期选择器的大小。
恕我直言,上面的解决方案是更好的选择,如果上述解决方案不适用于您的特定实现,那么这是一种替代方法。
extension UIDatePicker {
open override var intrinsicContentSize: CGSize {
CGSize(width: UIView.noIntrinsicMetric,
height: super.intrinsicContentSize.height)
}
}
...
DatePicker("", selection: $selection, displayedComponents: .hourAndMinute)
.datePickerStyle(.wheel)
.labelsHidden()
.fixedSize(horizontal: false, vertical: true)
.frame(alignment: .center)
.padding(.horizontal, 8.0)
感谢这篇文章给了我扩展的想法
可以轻松手动更改日期选择器的大小。如果您转到 Main.storyboard 并只需单击日期选择器,则可以轻松调整其大小。但是,我不确定这是否可以通过代码实现。
希望您觉得这有帮助。