如何改变DatePicker的大小?

问题描述 投票:0回答:6

有人知道如何更改 SwiftUI 中默认 DatePicker 的大小吗?我一直在尝试提供一个自定义框架来调整 DatePicker 的大小,但我看不到预期的结果。

这是我尝试过的:

DatePicker("", selection: $currentDate, displayedComponents: .hourAndMinute)
  .labelsHidden()
  .frame(width: 150, height: 80, alignment: .center)
swiftui
6个回答
13
投票

只需将其夹在末端即可,如下所示...

DatePicker("", selection: $currentDate, displayedComponents: .hourAndMinute)
    .labelsHidden()
    .frame(width: 150, height: 80, alignment: .center)
    .clipped()

6
投票

您可以使用变换效果更改其大小,此示例会将 DatePicker 大小减小为其默认大小的 0.8 只需将此修改器添加到选择器

DatePicker(......).transformEffect(.init(scaleX: 0.8, y: 0.8))

5
投票

我在日期选择器后面添加了.scaleEffect(),现在我可以实现尺寸缩放...


3
投票

虽然改变原生

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)
    }
}

0
投票

这个解决方案在我的情况下不起作用,因为我无法将宽度传递到

.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)

感谢这篇文章给了我扩展的想法


-6
投票

可以轻松手动更改日期选择器的大小。如果您转到 Main.storyboard 并只需单击日期选择器,则可以轻松调整其大小。但是,我不确定这是否可以通过代码实现。

希望您觉得这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.