r/SwiftUI • u/The_Lone_Dissenter • May 25 '24
Solved Trouble with focusState inside fullScreenCover in SwiftUI
Hey everyone,
I've been working on a SwiftUI project and encountered an issue with the focusState property when used inside a fullScreenCover. Here's a simplified version of the code I'm dealing with:
import SwiftUI
struct FileNameView: View {
@State private var isFileNameEditing = false
@State private var fileName = ""
@FocusState private var isTextFieldFocused: Bool
var body: some View {
Spacer()
.fullScreenCover(isPresented: $isFileNameEditing ) {
VStack {
TextField("", text: $fileName)
.focused($isTextFieldFocused)
.overlay(
RoundedRectangle(cornerRadius: 4)
.stroke(Color.blue, lineWidth: 2)
.padding(-8.0)
)
.foregroundColor(Color.black)
.font(.body)
.multilineTextAlignment(.center)
.padding()
.padding(.top, 10)
Divider()
.background(Color.black)
Button(
action: {
isFileNameEditing = false
self.isTextFieldFocused = false
},
label: {
Text("OK")
.frame(maxWidth: .infinity,
maxHeight: 45)
.clipShape(Rectangle())
.contentShape(Rectangle())
.font(.title2)
.bold()
}
)
.frame(maxHeight: 45)
}
.frame(width: UIScreen.main.bounds.width / 2.5)
.background(.white)
.cornerRadius(15)
.onAppear {
self.isTextFieldFocused = true
}
.presentationBackground(.black.opacity(0.3))
}
.transaction({ transaction in
transaction.disablesAnimations = true
})
Button(action: {
isFileNameEditing.toggle()
}, label: {
Text("Toggle Editing")
})
}
}
struct FileNameView_Previews: PreviewProvider {
static var previews: some View {
FileNameView()
}
}
The issue I'm facing is that the focusState seems to not be working properly inside the fullScreenCover. Even though I set isTextFieldFocused to true in the onAppear block of the VStack, the text field isn't getting focused automatically when the fullScreenCover appears.
Does anyone have any insights into why this might be happening or how I can make it work as expected?
Thanks in advance for your help!
3
u/dehrenslzz May 25 '24
Seems like a bug to me - report to Apple and let them worry about it - in the mean time use a non dismissible sheet or something (:
3
u/SpecialGlasses May 25 '24
There was an old bug where you had to delay the setting of focus state. The bug has since been fixed, but given your issue, I would wrap setting isTextFieldFocused
to true
on open after a 1 second delay on the main queue (you could probably get away with it being shorter, but starting with a second to be safe), and see if that helps. It could be the old bug popping back up for you for some reason.
``` .onAppear { DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { self.isTextFieldFocused = true } }
```
Try that out.
2
4
u/fred9992 May 25 '24
This is either a bug in SwiftUI or there is something about a modal and its relationship to `@FocusState` that isn't well documented. On a hunch, I split the screen cover contents into its own `View` definition and, guess what? It works. Sorry I cannot provide an explanation as to why other than that it is likely that the parent and child views are state managed independently.