📝
modifierでsheetを表示すると、そのsheetにあるTextFieldでfocusedが機能しない
タイトルの通り
改めて眺めると、sheetに表示するViewを切り出す方が自然な気がしてきた。
import SwiftUI
@main
struct SwiftDataSampleApp: App {
var body: some Scene {
WindowGroup {
ContentView(viewModel: ViewModel())
}
}
}
import SwiftUI
class ViewModel: ObservableObject {
@Published var text1: String = "123"
@Published var text2: String = "456"
@Published var showSheet: Bool = false
}
struct ContentView: View {
@ObservedObject var viewModel: ViewModel
var body: some View {
VStack {
Button(action: {
viewModel.showSheet.toggle()
}) {
Text("Open")
}
}
.modifier(SheetModifier(viewModel: self.viewModel))
}
}
struct SheetModifier: ViewModifier {
enum Field: Hashable {
case text1
case text2
}
@ObservedObject var viewModel: ViewModel
@FocusState var isFocused: Field?
func body(content: Content) -> some View {
return content
.sheet(isPresented: $viewModel.showSheet) {
VStack {
Spacer()
GroupBox {
VStack {
TextField("", text: $viewModel.text1)
.focused($isFocused, equals: .text1)
.keyboardType(.numbersAndPunctuation)
.multilineTextAlignment(.trailing)
.textFieldStyle(.roundedBorder)
TextField("", text: $viewModel.text2)
.focused($isFocused, equals: .text2)
.keyboardType(.numbersAndPunctuation)
.multilineTextAlignment(.trailing)
.textFieldStyle(.roundedBorder)
}
}
.onTapGesture {
print("onTapGesture \(isFocused)")
// ここでisFocusedにnilを代入してキーボードを閉じたい
}
Spacer()
}
.presentationDetents([.medium])
}
}
}
#Preview {
ContentView(viewModel: ViewModel())
}
というわけで、書き直したら機能した。
import SwiftUI
class ViewModel: ObservableObject {
@Published var text1: String = "123"
@Published var text2: String = "456"
@Published var showSheet: Bool = false
}
struct ContentView: View {
@ObservedObject var viewModel: ViewModel
var body: some View {
VStack {
Button(action: {
viewModel.showSheet.toggle()
}) {
Text("Open")
}
}
.sheet(isPresented: $viewModel.showSheet) {
SheetView(viewModel: self.viewModel)
.presentationDetents([.medium])
}
}
}
struct SheetView: View {
enum Field: Hashable {
case text1
case text2
}
@ObservedObject var viewModel: ViewModel
@FocusState var isFocused: Field?
var body: some View {
VStack {
Spacer()
GroupBox {
VStack {
TextField("", text: $viewModel.text1)
.focused($isFocused, equals: .text1)
.keyboardType(.numbersAndPunctuation)
.multilineTextAlignment(.trailing)
.textFieldStyle(.roundedBorder)
TextField("", text: $viewModel.text2)
.focused($isFocused, equals: .text2)
.keyboardType(.numbersAndPunctuation)
.multilineTextAlignment(.trailing)
.textFieldStyle(.roundedBorder)
}
}
.onTapGesture {
print("onTapGesture \(isFocused)")
}
Spacer()
}
}
}
#Preview {
ContentView(viewModel: ViewModel())
}
Discussion