我正在尋找一種方法來簡化/重構在具有許多 TextField 的 SwiftUI 視圖中添加 .onChange(of:) 的方法。如果解決方案簡潔,我還會將修飾符移近適當的欄位,而不是在 ScrollView 的末尾。在這種情況下,所有 .onChange 修飾符都呼叫相同的函式。
例子:
.onChange(of: patientDetailVM.pubFirstName) { x in
changeBackButton()
}
.onChange(of: patientDetailVM.pubLastName) { x in
changeBackButton()
}
// ten more times for other fields
我嘗試“oring”欄位。這不起作用:
.onChange(of:
patientDetailVM.pubFirstName ||
patientDetailVM.pubLastName
) { x in
changeBackButton()
}
這是我要呼叫的簡單函式:
func changeBackButton() {
withAnimation {
showBackButton = false
isEditing = true
}
}
任何指導將不勝感激。Xcode 13.2.1 iOS 15
uj5u.com熱心網友回復:
任何時候復制代碼時,您都希望將其向下移動一級,以便可以重復使用相同的代碼。
這是一個解決方案,父視圖將保存一個變數,該變數將知道“名稱”作為一個整體是否發生了變化。
import SwiftUI
class PatientDetailViewModel: ObservableObject{
@Published var pubFirstName: String = "John"
@Published var pubLastName: String = "Smith"
}
struct TrackingChangesView: View {
@StateObject var vm: PatientDetailViewModel = PatientDetailViewModel()
///Variable to know if there is a change
@State var nameHasChanges: Bool = false
var body: some View {
NavigationView{
NavigationLink("EditView", destination: {
VStack{
TrackingChangesTextFieldView(hasChanges: $nameHasChanges, text: $vm.pubFirstName, titleKey: "first name")
TrackingChangesTextFieldView(hasChanges: $nameHasChanges, text: $vm.pubLastName, titleKey: "last name")
Button("save", action: {
//Once you verify saving the object reset the variable
nameHasChanges = false
})//Enable button when there are changes
.disabled(!nameHasChanges)
}
//Or track the single variable here
.onChange(of: nameHasChanges, perform: {val in
//Your method here
})
//trigger back button with variable
.navigationBarBackButtonHidden(nameHasChanges)
})
}
}
}
struct TrackingChangesTextFieldView: View {
//Lets the parent view know that there has been a change
@Binding var hasChanges: Bool
@Binding var text: String
let titleKey: String
var body: some View {
TextField(titleKey, text: $text)
.onChange(of: text, perform: { _ in
//To keep it from reloading view if already true
if !hasChanges{
hasChanges = true
}
})
}
}
struct TrackingChangesView_Previews: PreviewProvider {
static var previews: some View {
TrackingChangesView()
}
}
uj5u.com熱心網友回復:
你能做到這一點的另一種方式是讓兩個組合出版商pubFirstName和pubLastName。將以下功能添加到您的viewModel
var nameChanged: AnyPublisher<Bool, Never> {
$patientDetailVM.pubFirstName
.combineLatest($patientDetailVM.pubLastName)
.map { firstName, lastName in
if firstName != patientDetailVM.pubFirstName ||
lastName != patientDetailVM.pubLastName
{
return true
} else {
return false
}
}
.eraseToAnyPublisher()
}
并聽取nameChanged出版商onReceive的意見
.onReceive(of: patientDetailVM.nameChanged) { hasNameChanged in
changeBackButton()
}
所以你可以聽名字或姓氏的變化。沒有測驗代碼,只是作為一個想法。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/387241.html
