SwiftUI Datepicker changes format after selecting date - ios

I've implemented a DatePicker with SwiftUI.
It works for the most part as is should, but when selecting a specific date, e.g 26. Nov 2019, it changes the format of the displayed date text.
Exampels:
Expected: 26. Nov 2019
Got: 26.11.2019
Expected 27. Nov 2019
Got: 27. Nov 2019
I have tried using the environment with a specific locale but it did not fix it.
Building my own DatePicker works, but it's not what I want.
The DatePicker also print this in the console:
UIDatePicker is being laid out below its minimum width of 280. This may not look like expected, especially with larger than normal font sizes.
This is my SwiftUI code:
private struct GeneralSection: View {
#ObservedObject var viewController: SettingsViewController
var body: some View {
Section(header: Text("General")) {
TextField("Name", text: $viewController.coupleName)
DatePicker(LocalizedStringKey("Date"),
selection: $viewController.coupleDate,
in: ...Date(),
displayedComponents: .date)
}
}
}
Gif from this problem

Related

How to change timezone of DatePicker in SwiftUI

I'm trying to make an mobile app for a reservation system. Users can reserve the product from different timezones. So when a user from NY city tries to reserve a product from Paris, I need to be sure user selected the time in Europe/Paris timezone. Currently swiftUI datepicker uses the system current timezone which is of course GMT-5 so when they select 13:00 the Date() object sets itself to 18:00 UTC, but I need him/her to be select in GMT+1 so when they select 13:00 I should set the Date() object to 12:00 UTC. I have tried to use environment value for timezone but it changes the timezone application wide, I just need to change the timezone of datepicker not all application.
Here are the solutions I've tried to change timezone
DatePicker("", selection: $viewModel.tripRequest.date, displayedComponents: .hourAndMinute)
.labelsHidden()
.padding(.horizontal)
.font(.custom("Gilroy-Regular", size: 36))
.cornerRadius(15)
.environment(\.timeZone, TimeZone(secondsFromGMT: 3600)!)
I've also tried to use introspect with no luck
DatePicker("", selection: $viewModel.tripRequest.date, displayedComponents: .hourAndMinute)
.labelsHidden()
.padding(.horizontal)
.font(.custom("Gilroy-Regular", size: 36))
.cornerRadius(15)
.introspectDatePicker { datePicker in
datePicker.timeZone = TimeZone(secondsFromGMT: 3600)
}
SwiftUI's DatePicker uses the device's Timezone by default.
You can specify a Timezone using .environment(\.timeZone, TimeZone(identifier: "Specific identifier")!)
But Date is in UTC so if the user picks a date in one timezone when viewed in another timezone it will be adjusted. You can't change the timezone for Date.
import SwiftUI
struct WorldTimeView: View {
#State private var date: Date = .init()
var body: some View {
VStack{
DatePicker("US", selection: $date, displayedComponents: .hourAndMinute)
//US Date Picker
.environment(\.timeZone, TimeZone(identifier: "America/New_York")!)
DatePicker("Paris", selection: $date, displayedComponents: .hourAndMinute)
//Paris Date Picker
.environment(\.timeZone, TimeZone(abbreviation: "CET")!)
//User/Device Date Picker
DatePicker("Local", selection: $date, displayedComponents: .hourAndMinute)
}
}
}
struct WorldTimeView_Previews: PreviewProvider {
static var previews: some View {
WorldTimeView()
}
}

SwiftUI DatePicker not selecting in sheet

Im using the native DatePicker in swiftUI presented through a sheet. The date picker it self is of graphical style. When the sheet is presented I can scroll through months but I cannot make a selection. To make a selection I have to constantly press on the date for 5-6 seconds. But if I use a wheel style everything works as expected. Im not sure if this is an iOS bug or something I am missing. Note: code works on preview_provider but not on actual device.
#State var showCalendar:Bool = false
#State var selectedDate:Date = Date()
.sheet(isPresented: $showCalendar){
VStack{
DatePicker("", selection: $selectedDate, displayedComponents: [.date])
.datePickerStyle(.graphical)
Spacer()
}
}

SwiftUI Picker iOS 16 not filling available space

I am using the following code (example) to render a SwiftUI Picker on iOS:
let strings: [String] = ["short", "very, ver long string"]
#State var selectedString: String = ""
Form {
Picker("Method", selection: $selectedString) {
ForEach(strings, id: \.self) { string in
Text(string)
}
}
}
In iOS 16 the design of the menu style picker has changed (it now includes 2 small chevrons), which is all good, except it no longer fills the available width (as it did on iOS 15). This results in longer strings flowing onto multiple lines even when this isn't neccessary.
Short String (all fine):
Long String (not so good):
I have tried .fixedSize(), which works to some extend but if the string does in fact need to be on two lines this forces the label to be squished. If I add a background to the Picker, it is clear that it only fills around 1/3 of the available space.
Does anyone have any suggestions?
Separate the label from the Picker and wrap it in a HStack.
Form {
HStack {
// the new label text
Text("Method")
.fixedSize() // give other views in HStack space to grow
// push the external label and Picker to the leading and trailing view edges
Spacer()
Picker("Method", selection: $selectedString) {
ForEach(strings, id: \.self) { string in
Text(string)
}
}
.labelsHidden() // the label is in the Text view
}
}
Hide the Picker label by using the .labelsHidden() modifier.
Use the .fixedSize() modifier on the new Text. This will allow the Picker to expand to fit all its contents.
Use Spacer between Text label and Picker to push both items to the edge.

SwiftUI: Why does a certain Text tracking value truncate the label?

When using a certain combination of text attributes (smallCaps, tracking, weight) in SwiftUI, the label text gets truncated.
I'm just wondering whether this is a bug, or if I'm doing something wrong here.
Please see the following Playground example:
import SwiftUI
import PlaygroundSupport
struct MyView: View {
var body: some View {
VStack {
// This works as expected.
Text("Longer Text")
.font(Font.system(.largeTitle).smallCaps())
.fontWeight(.semibold)
.tracking(15)
// Here, the text gets truncated, even though there is
// a smaller tracking value set, and there would be enough
// space to show the complete text.
Text("Longer Text")
.font(Font.system(.largeTitle).smallCaps())
.fontWeight(.semibold)
.tracking(10)
// This works as expected.
Text("Longer Text")
.font(Font.system(.largeTitle).smallCaps())
.fontWeight(.semibold)
.kerning(15)
// This works as expected.
Text("Longer Text")
.font(Font.system(.largeTitle).smallCaps())
.fontWeight(.semibold)
.kerning(10)
}
}
}
PlaygroundPage.current.setLiveView(MyView())
Result:
I'm using Xcode 11.4, Swift 5.2, and tested in a Playground, on simulators (iOS 13.4), and an iPad (iOS 13.3.1).

Make the TextField Multiline - SwiftUI [duplicate]

This question already has answers here:
How do I create a multiline TextField in SwiftUI?
(17 answers)
Closed 9 months ago.
I start learning SwiftUI and I'm trying to make the TextField multiline but it didn't work, also when I click on the return button it dismisses the keyboard.
TextField("Description", text: $categoryTitle)
.lineLimit(nil)
so how I can fix it?
Since iOS 16
The lineLimit modifier works as expected if you choose .vertical value for the axis parameter. And it also supports range now:
TextField("Title", text: $text, axis: .vertical)
.lineLimit(5...10)
Since iOS 14
Form iOS 14 and with Xcode 12, it's available as TextEditor
struct ContentView: View {
#State var text: String = "Multiline \ntext \nis called \nTextEditor"
var body: some View {
TextEditor(text: $text)
}
}
iOS 13
Also, if you want to support iOS 13, you can take at look this answer to port UITextField inside SwiftUI with full access to all of its properties.
iOS 16.0+ supprts multiline TextField.
struct ContentView: View {
#State private var description: String = """
Join us, and let's force unwrap SwiftUl's
birthday presents. Note that although
this activity is optional, we may have
guards at the entry.
"""
var body: some View {
Form {
TextField("Description", text: $description, axis: .vertical)
.lineLimit(5) // You can restrict min & max visible lines
}
}
}

Resources