SwiftUI UIDatePicker .compact 不直接弹出
SwiftUI UIDatePicker .compact doesn't go directly to pop-up
我使用 UIDatePicker
创建了一个自定义 DatePicker,当我 select 该字段时,它将日期和时间作为一个选项显示在屏幕底部,而无需直接转到弹出窗口.不知道怎么形容,请看下图:
请看下面我的代码:
import SwiftUI
struct CustomDateTimePicker: View {
@State private var date: Date?
@State private var time: String? = "Time"
var body: some View {
HStack {
Image("Time")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 22.0, height: 22.0, alignment: .center)
DateField("", date: self.$date)
.font(.system(size: 19, weight: .light, design: .rounded))
.foregroundColor(Color.gray)
}.padding()
.frame(width: 200, height: 100)
.background(Color.white)
.cornerRadius(8)
.shadow(color: Color.black.opacity(0.1), radius: 30, x: 0 , y: 15)
}
}
class DateTextField: UITextField {
// MARK: - Public properties
@Binding var date: Date?
// MARK: - Initializers
init(date: Binding<Date?>) {
self._date = date
super.init(frame: .zero)
if let date = date.wrappedValue {
self.datePickerView.date = date
}
self.datePickerView.addTarget(self, action: #selector(dateChanged(_:)), for: .valueChanged)
self.inputView = datePickerView
self.tintColor = .clear
self.font = UIFont.systemFont(ofSize: 18.0, weight: .medium)
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - Private properties
private lazy var datePickerView: UIDatePicker = {
let datePickerView = UIDatePicker()
datePickerView.datePickerMode = .dateAndTime
datePickerView.minuteInterval = 5
if #available(iOS 14.0, *) {
datePickerView.preferredDatePickerStyle = .compact
datePickerView.sizeToFit()
} else {
datePickerView.preferredDatePickerStyle = .wheels
}
return datePickerView
}()
// MARK: - Private methods
@objc func dateChanged(_ sender: UIDatePicker) {
self.date = sender.date
}
}
struct DateField: UIViewRepresentable {
// MARK: - Public properties
@Binding var date: Date?
// MARK: - Initializers
init<S>(_ title: S, date: Binding<Date?>, formatter: DateFormatter = .yearMonthDay) where S: StringProtocol {
self.placeholder = String(title)
self._date = date
self.textField = DateTextField(date: date)
self.formatter = formatter
}
// MARK: - Public methods
func makeUIView(context: UIViewRepresentableContext<DateField>) -> UITextField {
textField.placeholder = placeholder
return textField
}
func updateUIView(_ uiView: UITextField, context: UIViewRepresentableContext<DateField>) {
if let date = date {
uiView.text = formatter.string(from: date)
}
}
// MARK: - Private properties
private var placeholder: String
private let formatter: DateFormatter
private let textField: DateTextField
}
extension DateFormatter {
static var yearMonthDay: DateFormatter {
let formatter = DateFormatter()
formatter.dateFormat = "dd MMM yyyy HH:mm"
return formatter
}
}
struct CustomDateTimePicker_Previews: PreviewProvider {
static var previews: some View {
CustomDateTimePicker()
}
}
如何在单击我的字段后显示紧凑菜单,而不必选择底部的 date/time?
使用 Compact DatePicker 时,如果不从显示在底部的部分中选择日历,则无法自动显示日历。
Open UIDatePicker programmatically in iOS 14
您可以(如果 5 分钟间隔不是必需的)使用 GraphicalDatePickerStyle
,它显示非常相似的日历。
struct ParentDatePicker: View {
@State var showGraphical: Bool = false
@State var currentDate: Date = Date()
var dateFormatter: DateFormatter {
let formatter = DateFormatter()
formatter.dateFormat = "dd MMM yyyy HH:mm"
return formatter
}
var body: some View {
Button(action: {
showGraphical.toggle()
}, label: {
Label(
title: { Text("\(currentDate, formatter: dateFormatter)") },
icon: { Image(systemName: "clock") })
})
.padding()
.frame(width: 200, height: 100)
.background(Color.white)
.cornerRadius(8)
.shadow(color: Color.black.opacity(0.1), radius: 30, x: 0 , y: 15)
.sheet(isPresented: $showGraphical, content: {
CusDatePicker(currentDate: $currentDate)
})
}
}
struct CusDatePicker: View {
@Binding var currentDate: Date
var body: some View {
//https://developer.apple.com/documentation/swiftui/datepicker
DatePicker("Date", selection: $currentDate, displayedComponents: [.date, .hourAndMinute])
//.datePickerStyle(CompactDatePickerStyle())
.datePickerStyle(GraphicalDatePickerStyle())
}
}
struct CusDatePicker_Previews: PreviewProvider {
static var previews: some View {
ParentDatePicker()
}
}
我使用 UIDatePicker
创建了一个自定义 DatePicker,当我 select 该字段时,它将日期和时间作为一个选项显示在屏幕底部,而无需直接转到弹出窗口.不知道怎么形容,请看下图:
请看下面我的代码:
import SwiftUI
struct CustomDateTimePicker: View {
@State private var date: Date?
@State private var time: String? = "Time"
var body: some View {
HStack {
Image("Time")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 22.0, height: 22.0, alignment: .center)
DateField("", date: self.$date)
.font(.system(size: 19, weight: .light, design: .rounded))
.foregroundColor(Color.gray)
}.padding()
.frame(width: 200, height: 100)
.background(Color.white)
.cornerRadius(8)
.shadow(color: Color.black.opacity(0.1), radius: 30, x: 0 , y: 15)
}
}
class DateTextField: UITextField {
// MARK: - Public properties
@Binding var date: Date?
// MARK: - Initializers
init(date: Binding<Date?>) {
self._date = date
super.init(frame: .zero)
if let date = date.wrappedValue {
self.datePickerView.date = date
}
self.datePickerView.addTarget(self, action: #selector(dateChanged(_:)), for: .valueChanged)
self.inputView = datePickerView
self.tintColor = .clear
self.font = UIFont.systemFont(ofSize: 18.0, weight: .medium)
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - Private properties
private lazy var datePickerView: UIDatePicker = {
let datePickerView = UIDatePicker()
datePickerView.datePickerMode = .dateAndTime
datePickerView.minuteInterval = 5
if #available(iOS 14.0, *) {
datePickerView.preferredDatePickerStyle = .compact
datePickerView.sizeToFit()
} else {
datePickerView.preferredDatePickerStyle = .wheels
}
return datePickerView
}()
// MARK: - Private methods
@objc func dateChanged(_ sender: UIDatePicker) {
self.date = sender.date
}
}
struct DateField: UIViewRepresentable {
// MARK: - Public properties
@Binding var date: Date?
// MARK: - Initializers
init<S>(_ title: S, date: Binding<Date?>, formatter: DateFormatter = .yearMonthDay) where S: StringProtocol {
self.placeholder = String(title)
self._date = date
self.textField = DateTextField(date: date)
self.formatter = formatter
}
// MARK: - Public methods
func makeUIView(context: UIViewRepresentableContext<DateField>) -> UITextField {
textField.placeholder = placeholder
return textField
}
func updateUIView(_ uiView: UITextField, context: UIViewRepresentableContext<DateField>) {
if let date = date {
uiView.text = formatter.string(from: date)
}
}
// MARK: - Private properties
private var placeholder: String
private let formatter: DateFormatter
private let textField: DateTextField
}
extension DateFormatter {
static var yearMonthDay: DateFormatter {
let formatter = DateFormatter()
formatter.dateFormat = "dd MMM yyyy HH:mm"
return formatter
}
}
struct CustomDateTimePicker_Previews: PreviewProvider {
static var previews: some View {
CustomDateTimePicker()
}
}
如何在单击我的字段后显示紧凑菜单,而不必选择底部的 date/time?
使用 Compact DatePicker 时,如果不从显示在底部的部分中选择日历,则无法自动显示日历。 Open UIDatePicker programmatically in iOS 14
您可以(如果 5 分钟间隔不是必需的)使用 GraphicalDatePickerStyle
,它显示非常相似的日历。
struct ParentDatePicker: View {
@State var showGraphical: Bool = false
@State var currentDate: Date = Date()
var dateFormatter: DateFormatter {
let formatter = DateFormatter()
formatter.dateFormat = "dd MMM yyyy HH:mm"
return formatter
}
var body: some View {
Button(action: {
showGraphical.toggle()
}, label: {
Label(
title: { Text("\(currentDate, formatter: dateFormatter)") },
icon: { Image(systemName: "clock") })
})
.padding()
.frame(width: 200, height: 100)
.background(Color.white)
.cornerRadius(8)
.shadow(color: Color.black.opacity(0.1), radius: 30, x: 0 , y: 15)
.sheet(isPresented: $showGraphical, content: {
CusDatePicker(currentDate: $currentDate)
})
}
}
struct CusDatePicker: View {
@Binding var currentDate: Date
var body: some View {
//https://developer.apple.com/documentation/swiftui/datepicker
DatePicker("Date", selection: $currentDate, displayedComponents: [.date, .hourAndMinute])
//.datePickerStyle(CompactDatePickerStyle())
.datePickerStyle(GraphicalDatePickerStyle())
}
}
struct CusDatePicker_Previews: PreviewProvider {
static var previews: some View {
ParentDatePicker()
}
}