SwiftUI:具有自定义设计的紧凑型日期选择器

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

我需要一个自定义“标签”,其行为是在某种弹出窗口中打开日期选择器,即使在 iPhone 上也是如此。

当我使用紧凑格式的内置 DatePicker 时,我有在弹出窗口中打开轮子的行为,但我无法自定义带有灰色背景的“折叠”版本的外观(事实上,我可以将其更改为一些其他颜色,但不能是白色,例如,它根本不起作用)。

另一种选择是将自定义的

Text
包裹在
Button
内,然后打开DatePicker,但我不知道如何在iPhone上实现弹出框效果。所以我想第一个选项会更容易,但是如何为紧凑的日期选择器实现自定义布局?没什么特别的,就是这样的:

而不是像这样的东西

swiftui datepicker
2个回答
5
投票

它更多的是概念证明,但这可能是一种方法:


import SwiftUI

struct ContentView: View {
    @State private var showPicker = true
    @State var selectedDate = Date()

        Button {
            withAnimation {
                showPicker.toggle()
            }
        }  label: {
            Text(Text(selectedDate.getFormattedDate(format:"HH:mm:")))
                .padding()
                .padding(.horizontal)
                .background(
                    RoundedRectangle(cornerRadius: 10)
                        .stroke(Color.gray)
                )
        }
        .background(
            DatePicker("", selection: $selectedDate, displayedComponents: .hourAndMinute)
                .datePickerStyle(.wheel)
                .frame(width: 200, height: 100)
                .clipped()
                .background(Color.gray.cornerRadius(10))
                .opacity(showPicker ? 1 : 0 )
                .offset(x: 50, y: 90)
               ).onChange(of: selectedDate) { newValue in
                   
                   withAnimation {
                       showPicker.toggle()
                   }
               }
}

请注意,DidSet 或 willSet 对于对象来说是不可能的,但是,我们有一个很好的解决方法 onChange。当日期更改时,只需切换即可完成。


0
投票

这有点 hacky,但另一种方法是将实际

DatePicker
视图的不透明度设置为
0.011
(这是最大不透明度),然后使用
.overlay
将其放在自定义视图之上,这是一个示例:

struct MyDatePicker: View {
    @State private var displayDate: String = {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "MMM d, yyyy"
        return dateFormatter.string(from: Date())
    }()

    @State private var selectedDate = Date()

    var body: some View {

        // Put your own design here
        HStack(spacing: 2) {
            Text(displayDate)
                .font(.system(size: 13, weight: .semibold))
        
            Image(systemName: "chevron.right")
                .font(.system(size: 9, weight: .bold))
        }
        .padding(8)
        .foregroundColor(.white)
        .background(RoundedRectangle(cornerRadius: 15, style: .continuous).foregroundColor(.blue))

        // Put the actual DatePicker view here
        .overlay {
            DatePicker(selection: $selectedDate, displayedComponents: .date) {}
                .labelsHidden()
                .contentShape(Rectangle())
                .opacity(0.011)             // <<< here
        }
    }
}

结果如下:

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