I've been testing my app on iOS 17 Public Beta and noticed a bug where the FocusState always returns nil depending on the combination of Views.
This issue did not occur on iOS 16 and earlier.
Below is the code where FocusState does not work.
As far as I've checked, the issue only occurs in the case below. Does anyone have a workaround?
Test environment:
- Xcode Version 15.0 (15A240d)
- iOS 17.0(21A329) (iPhone)
@main
struct SampleApp: App {
var body: some Scene {
WindowGroup {
ContentView() ///<-- 1
}
}
}
struct ContentView: View {
@State var isShowingCover = false
var body: some View {
Button("Show") {
isShowingCover = true
}
.fullScreenCover(isPresented: $isShowingCover) {
NavigationStack { ///<-- 2
SheetView()
}
}
}
}
struct SheetView: View {
@State private var texts: [String] = [
"file",
"folder",
]
@FocusState var focusing: Int?
var body: some View {
VStack {
Text("focusing: \(String(describing: focusing))")
List { ///<-- 3
TextFields(texts: $texts, focusing: $focusing)
}
Button(">") {
// FocusState always becomes nil in iOS 17
if let focusing { self.focusing = (focusing + 1) % texts.count }
else { self.focusing = 0 }
}
}
}
}
public struct TextFields: View {
@Binding var texts: [String]
var focusing: FocusState<Int?>.Binding
public var body: some View {
HStack {
ForEach(texts.indices, id: \.self) { idx in
TextField("", text: $texts[idx])
.focused(focusing, equals: idx)
.underline(idx == focusing.wrappedValue)
}
}
}
}
Interestingly, removing the NavigationStack within fullScreenCover makes FocusState work as expected. (2)
Also, if the ContentView in WindowGroup is changed to NavigationStack { SheetView() } (1) or the List (3) is removed, FocusState still works as expected.
/// 1
@main
struct MultilineFieldSampleApp: App {
var body: some Scene {
WindowGroup {
// ContentView()
NavigationStack {
SheetView() // FocusState works.
}
}
}
}
///2
struct ContentView: View {
@State var isShowingCover = false
var body: some View {
Button("Show") {
isShowingCover = true
}
.fullScreenCover(isPresented: $isShowingCover) {
// NavigationStack {
SheetView() // Also, FocusState works.
// }
}
}
}
/// 3
struct SheetView: View {
// ...
var body: some View {
VStack {
Text("focusing: \(String(describing: focusing))")
// List {
TextFields(texts: $texts, focusing: $focusing) // FocusState works.
// }
Button(">") {
if let focusing { self.focusing = (focusing + 1) % texts.count }
else { self.focusing = 0 }
}
}
}
}