Skip to content

Instantly share code, notes, and snippets.

@michael94ellis
Last active April 14, 2024 15:03
Show Gist options
  • Save michael94ellis/4e877ae9ddecf19b55bbc8b8248ac69f to your computer and use it in GitHub Desktop.
Save michael94ellis/4e877ae9ddecf19b55bbc8b8248ac69f to your computer and use it in GitHub Desktop.
TextField FocusState Demo for iOS 15 SwiftUI
//
// Focus State Example
//
// Created by Michael Robert Ellis on 12/7/21.
//
import SwiftUI
struct MyObject: Identifiable, Equatable {
var id: String
public var value: String
init(name: String, value: String) {
self.id = name
self.value = value
}
}
struct ContentView: View {
@State var myObjects: [MyObject] = [
MyObject(name: "aa", value: "1"),
MyObject(name: "bb", value: "2"),
MyObject(name: "cc", value: "3"),
MyObject(name: "dd", value: "4")
]
@State var focus: MyObject?
var body: some View {
ScrollView(.vertical) {
VStack {
Text("Header")
ForEach(self.myObjects) { obj in
Divider()
FocusField(displayObject: obj, focus: $focus, nextFocus: {
guard let index = self.myObjects.firstIndex(of: $0) else {
return
}
self.focus = myObjects.indices.contains(index + 1) ? myObjects[index + 1] : nil
})
}
Divider()
Text("Footer")
}
}
}
}
struct FocusField: View {
@State var displayObject: MyObject
@FocusState var isFocused: Bool
@Binding var focus: MyObject?
var nextFocus: (MyObject) -> Void
var body: some View {
TextField("Test", text: $displayObject.value)
.onChange(of: focus, perform: { newValue in
self.isFocused = newValue == displayObject
})
.focused(self.$isFocused)
.submitLabel(.next)
.onSubmit {
self.nextFocus(displayObject)
}
}
}
@eonist
Copy link

eonist commented Apr 14, 2024

A general purpose solution to this is to use a ViewModifier and FocusState that use UUID or Int.

@michael94ellis
Copy link
Author

michael94ellis commented Apr 14, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment