I have this code, modified from stuff posted elsewhere, for entering dates. It works pretty well, but the UITextField which displays the date chooses its own width and I haven't been able to work out how to modify it.
class DateEntry: UITextField, ObservableObject {
@Published var date = Date() {
didSet {
datePicker.date = date // updates the wheels when date is changed elswhere
}
}
private var datePicker = UIDatePicker()
init(date: Date = Date() {
self.date = date
super.init(frame: .zero)
inputView = datePicker
textColor = UIColor.systemBlue
textAlignment = NSTextAlignment.right
datePicker.addTarget(self, action: #selector(datePickerDidSelect(_:)), for: .valueChanged)
datePicker.datePickerMode = .date
datePicker.date = date
datePicker.preferredDatePickerStyle = .wheels
let toolBar = UIToolbar()
toolBar.isTranslucent = true
toolBar.sizeToFit()
let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(hideKeyboard))
toolBar.setItems([flexibleSpace, doneButton], animated: false)
inputAccessoryView = toolBar
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc private func datePickerDidSelect(_ sender: UIDatePicker) {
date = sender.date
}
@objc private func hideKeyboard() {
resignFirstResponder()
}
}
struct DateEntryView: UIViewRepresentable {
@ObservedObject var entry: DateEntry
func updateUIView(_ uiView: DateEntry, context: Context) {
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yyyy"
uiView.text = formatter.string(from: entry.date)
}
func makeUIView(context: Context) -> DateEntry {
return entry
}
}
In my content view, I have
var body: some View {
@StateObject var start = DateEntry()
@StateObject var end = DateEntry()
VStack (alignment: .leading) {
HStack {
Text("Start")
.frame(width: 70, height: 25, alignment: .leading)
DateEntryView(entry: start)
Spacer()
Text("End")
.frame(width: 60, height: 25, alignment: .leading)
DateEntryView(entry: end)
}
}
but no matter how I set the frame widths for the two Texts, I end up with
Start -big gap- DateEntryView -small gap- End -big gap- DateEntryView
which looks odd. The Spacer in the HStack seems to do nothing.
I've tried putting a frame modifer on the DatEntryView; I've tried specifying an initialised CGRect instead of .zero in the super.init call; I've tried putting more Spacer()s at the beginning and end, but nothing seems to affect the layout. How can I get control over the spacing / size of the DateEntryView view?
Any ideas gratefully received.
Jeremy