SwiftUI - Date Picker not showing correctly - swift

I´ve created a DatePicker element in SwiftUI, but the DatePicker opens inside the view instead of a sheet at the bottom. (Screenshot below)
My code:
#ObservedObject private var report = Report(
id: 0,
timestamp: Date(timeIntervalSinceReferenceDate: 118800),
date: Date(timeIntervalSinceReferenceDate: 118800),
)
Section(header: Text("Allgemeine Daten")) {
HStack {
Label(string: "Name")
Divider()
TextField("Name", text: $person.name)
}
HStack {
Label(string: "Monat")
Divider()
DatePicker(selection: $report.date, displayedComponents: .date) {
Text("Select a date")
}
}
}
The Section is inside a NavigationView and Form. What could be the issue?

This is because it's actually getting temporarily added to the view hierarchy where your DatePicker is. Since your date picker is in an HStack, it gets appended to the end of the HStack resulting in what you see. If you add the DatePicker by itself, then it gets added to the Section instead, and will shift content below. It's still a pretty terrible animation/user experience, though, so I have to assume it's a bug.

Related

SwiftUI Keyboard dismiss not interactive

Thanks for taking your time to help others :)
Problem description:
App must support iOS 14 (there's no keyboard toolbar), and cannot use Introspect library, sorry.
When using a TextField, I want to dismiss it interactively. It does dismiss the keyboard, but does not take TextField along. And it should.
Simple demo code to replicate what happens:
import SwiftUI
struct ContentView: View {
#State var text: String = ""
init() {
UIScrollView.appearance().keyboardDismissMode = .interactive // To interactively dismiss
}
var body: some View {
VStack {
ScrollView {
LazyVStack {
ForEach(1...200, id: \.self) { msg in
Text("Message \(msg)")
.padding()
.background(Color.red.cornerRadius(8))
}
}
}
TextField("Hello", text: $text)
.textFieldStyle(.roundedBorder)
.padding()
}
.navigationTitle("Example")
.navigationBarTitleDisplayMode(.inline)
}
}
GIF resources to see behaviour:
Good result:
Bad result:
What I have checked?
Registering the keyboard height through Notifications events, like in: this post and adding that height as offset, bottom padding... nothing works.
Any idea?

Make all View contained TextField be visible above keyboard

It is not question about how to keep TextField above keyboard (put it inside ScrollView), I wonder how to keep TextField containing View fully be visible above Keyboard. For example behind TextField some info text, which should be visible while user print the text.
VStack { // This all should be above keyboard
TextField(...)
Text("Some hints about entered text")
}
In screens:
Now I have this (you can see TextField just above keyboard, but we don't see content under TextField)
But I want to get this (With "Some additional info" label, which should also pop above keyboard when TextField become first responder):
I was try you code and all warks fine right now but you can try like this:
VStack(alignment: .leading) {
TextField(...)
Text("Some hints about entered text")
}
I don't know what I want because there's not much information I can get from the question, but is this right? I understand that you want to include a view that can be a hint from the view behind the TextField.
import SwiftUI
struct ContentView: View {
#State private var text = ""
var body: some View {
VStack { // This all should be above keyboard
Spacer()
TextField("", text: $text)
.background {
Text("Some hints about entered text")
.foregroundColor(.gray)
}
}
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

SwiftUI: Detected a case where constraints ambiguously suggest a height of zero for a table view cell's content view

How can I fix the reason why the warning appears?
struct ContentView: View {
#State private var selectedDate: Date = Date()
var body: some View {
Form {
DatePicker("Date", selection: $selectedDate, displayedComponents: .date)
}
}
}
A workaround solution would be to use a List View instead of a Form.
It all depends on what you want to put in your Form.
For demonstration purpose, using a List, your code would look like this:
struct ContentView: View {
#State private var selectedDate: Date = Date()
var body: some View {
List {
DatePicker("Date", selection: $selectedDate, displayedComponents: .date)
}
.listStyle(InsetGroupedListStyle())
}
}
The above gives the same visual effect (UI) as using a List, and no warning is shown.
Because everything is working correctly with your Form, I don't really see the need to change your Form to a List just to avoid the logs.

SwiftUI TextField takes max width

I have a navigation list with each list item being in this format:
HStack {
TextField("Insert something here.",text: self.$userData.pages[i].title)
.border(Color.blue)
Spacer()
}
This results in the following view:
The touchable area is highlighted by the blue border and it takes the whole width of the row
The problem with this is that despite the list item being a navigation link, the user clicking anywhere along the item will result in them editing the text content. What I would prefer is a TextField that has the same width as a Text:
The blue border wraps the text instead of taking the max width
So if the user clicks outside the TextField, the navigation works, but if they click on the text, it will let them edit the text. (The above view is with Text field).
Apologies if I've asked an unclear or bad question. I'm new to Stack Overflow and SwiftUI.
Edit:
I've tried using the fixedSize modifier, and the TextField correctly wraps my Text, but now the Navigation Link doesn't work (i.e. clicking on it just doesn't navigate). This is my full code:
NavigationLink(destination: PageView(page: self.userData.pages[i])) {
HStack {
Button(action: {}){
TextField(" ", text: self.$userData.pages[i].title)
.fixedSize()
}
.buttonStyle(MyButtonStyle())
.border(Color.blue)
Spacer()
}
}
No need to apologize, your question is clear.
You can do this by using fixedSize()
so your code should be like this
HStack {
TextField("Insert something here.",text: self.$userData.pages[i].title)
.border(Color.blue)
.fixedSize()
Spacer()
}
You can further specify how would you like the stretch to be, either vertical or horizontal or even both by passing parameters like so
.fixedSize(horizontal: true, vertical: false)
UPDATED ANSWER TO MATCH YOUR NEW REQUIREMENTS
import SwiftUI
struct StackOverflow5: View {
#State var text: String = ""
#State var selection: Int? = nil
var body: some View {
NavigationView {
ZStack {
NavigationLink(destination: Page2(), tag: 1, selection:self.$selection) {
Color.clear
.onTapGesture {
self.selection = 1
}
}
TextField("Text", text: self.$text)
.fixedSize()
}
}
}
}
struct StackOverflow5_Previews: PreviewProvider {
static var previews: some View {
StackOverflow5()
}
}
struct Page2: View {
var body: some View {
Text("Page2")
}
}
We used a ZStack here to separate between our TextField and our NavigationLink so they can be interacted with separately.
Note the use of Color.clear before our TextField and this is on purpose so that our TextField has interaction priority. Also we used Color.clear because it will stretch as a background and it's clear so it's not visible.
Obviously I hard coded 1 here but this can be from List or a ForEach
Additionally, if you don't want to use selection and tag you can do something like this
...
#State var isActive: Bool = false
...
NavigationLink(destination: Page2(), isActive: self.$isActive) {
Color.clear
.onTapGesture {
self.isActive.toggle()
}
}
....

How to prevent TextField from disappearing in SwiftUI List?

There's a nasty SwiftUI bug in which a TextField disappears if placed in a HStack within a List
List {
ForEach(0...200, id: \.self) { index in
HStack {
Text("Text \(index)")
TextField("Test", text: .constant("TextField \(index)"))
}
}
}
https://recordit.co/X12uGct7gD
This happens when TextField is placed within a HStack / VStack / ZStack / .overlay() / .background(). It does not happen when TextField is the only child of ForEach.
I have filed a bug (FB7500885) but I'm looking for ideas from the community to work around it. Here is what I've tried so far:
Setting an explicit .frame() on TextField
Setting .fixedSized() on TextField
Using a UITextField wrapped in a UIViewConvertible, with or without layout constraints
Is there anything else I could try?
Try the following one:
List {
ForEach(0...200, id: \.self) { index in
HStack {
Text("Text \(index)")
TextField("Test", text: .constant("TextField \(index)")).id(index)
}
}
}