SwiftUI UIDatePicker .compact 不会直接弹出 [英] SwiftUI UIDatePicker .compact doesn't go directly to pop-up

查看:46
本文介绍了SwiftUI UIDatePicker .compact 不会直接弹出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 UIDatePicker 创建了一个自定义 DatePicker,当我选择该字段时,它会在屏幕底部显示日期和时间作为选项,而无需直接进入弹出窗口.不知道怎么描述,请看下图:

I have created a custom DatePicker using UIDatePicker and when I select the field it displays the date and time as an option at the bottom of the screen without going directly to the pop-up. Not sure how to describe it so please see the image below:

请看下面我的代码:

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

如何在单击我的字段后显示紧凑菜单,而不必在底部选择日期/时间?

How can I have the compact menu be shown when after clicking on my field instead of having to choose the date/time at the bottom?

推荐答案

使用 Compact DatePicker,如果不从底部显示的部分中选择日历,则无法自动显示日历.在 iOS 14 中以编程方式打开 UIDatePicker

With the Compact DatePicker you can't automatically show the calendar without selecting it from the part that show up at the bottom. Open UIDatePicker programmatically in iOS 14

您可以(如果不需要 5 分钟间隔)使用 GraphicalDatePickerStyle,它显示了一个非常相似的日历.

You can (if the 5 minute interval isn't a requirement) use GraphicalDatePickerStyle which shows a very similar calendar.

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

这篇关于SwiftUI UIDatePicker .compact 不会直接弹出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆