Tenho uma view com a @FocusState
que quero passar para uma subview. Para a subview, uso @FocusState.Binding
. Isso funciona bem se eu não usar um inicializador personalizado... mas não consigo descobrir a sintaxe de como funciona com um inicializador de view personalizado, que preciso por outros motivos.
Aqui está o código que funciona:
struct TestListButtonsAndListFocusView: View {
@FocusState var buttonFocusState: ButtonState?
@ObservedObject var viewModel: ViewModel = ViewModel()
var body: some View {
TestListView(viewModel: viewModel, bindedFocusButtonState: $buttonFocusState) // for custom init, replace with following line
//TestListView(viewModel: viewModel, focusButtonState: $buttonFocusState) // 1. Uncomment this for custom initializer
}
}
struct TestListView: View {
@State private var items1: [TimedItem] = [
TimedItem(number: 1, timestamp: "2024-11-20 10:00"),
TimedItem(number: 2, timestamp: "2024-11-20 11:00"),
TimedItem(number: 3, timestamp: "2024-11-20 12:00")
]
@ObservedObject var viewModel: ViewModel
@FocusState.Binding var bindedFocusButtonState: ButtonState?
@State var selectedItem: TimedItem.ID?
var body: some View {
List(items1, selection: $selectedItem) { item in
ContentListItemView(item: item)
}
.onChange(of: bindedFocusButtonState) {
if let bindedFocusButtonState {
print("TestListView - bindedListFocusState has changed to \(bindedFocusButtonState)")
if bindedFocusButtonState == .one && selectedItem == nil {
selectedItem = items1.first?.id
}
} else {
print("ListOneView - bindedListFocusState has changed to nil")
}
}
}
// 2. Uncomment this
/*init(viewModel: ViewModel, focusButtonState: FocusState<ButtonState?>.Binding) {
// how to pass in @FocusState.Binding?
self.viewModel = viewModel
self.bindedFocusButtonState = focusButtonState
// Error: Cannot assign value of type 'FocusState<ButtonState?>.Binding' to type 'ButtonState?'
}*/
}
public class ViewModel: NSObject, ObservableObject {
@Published public var selectedButton: ButtonState? = ButtonState.one
}
public enum ButtonState: Int, CaseIterable, Hashable, Identifiable {
public var id: Self {
return self
}
case one, two, three
}
#Preview {
TestListButtonsAndListFocusView()
}
Entretanto, se eu descomentar a linha para o inicializador personalizado e, em seguida, inserir a linha TestListButtonsAndListFocusView
para usar o inicializador personalizado, a sintaxe estará errada e eu recebo o erro:
Erro: Não é possível atribuir valor do tipo 'FocusState<ButtonState?>.Binding' ao tipo 'ButtonState?'
Não tenho certeza de como inicializar dessa @FocusState.Binding
forma. Sei que funciona se eu usar var bindedFocusButtonState: FocusState<ContactTabStyle?>.Binding
em vez disso, e então usar isso no inicializador também. Mas eu realmente gostaria de descobrir como usar o novo @FocusState.Binding
com o inicializador personalizado, pois evita ter que acessar wrappedValue
e é mais fácil de observar comonChange
Você deve atribuir à propriedade prefixada com sublinhado
_bindedFocusButtonState
.Esta é a propriedade que realmente contém o
FocusState.Binding
.bindedFocusButtonState
Por outro lado, é na verdade uma propriedade computada que retorna_bindedFocusButtonState.wrappedValue
.Em particular, a linha
declara três propriedades: