我需要一个自定义“标签”,其行为是在某种弹出窗口中打开日期选择器,即使在 iPhone 上也是如此。
当我使用紧凑格式的内置 DatePicker 时,我有在弹出窗口中打开轮子的行为,但我无法自定义带有灰色背景的“折叠”版本的外观(事实上,我可以将其更改为一些其他颜色,但不能是白色,例如,它根本不起作用)。
另一种选择是将自定义的
Text
包裹在Button
内,然后打开DatePicker,但我不知道如何在iPhone上实现弹出框效果。所以我想第一个选项会更容易,但是如何为紧凑的日期选择器实现自定义布局?没什么特别的,就是这样的:
而不是像这样的东西
它更多的是概念证明,但这可能是一种方法:
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。当日期更改时,只需切换即可完成。
这有点 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
}
}
}