use*_*617 14 xcode ios swiftui
我正在寻找一种方法来简化/重构在具有许多文本字段的 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
Run Code Online (Sandbox Code Playgroud)
我尝试“oring”字段。这不起作用:
.onChange(of:
patientDetailVM.pubFirstName ||
patientDetailVM.pubLastName
) { x in
changeBackButton()
}
Run Code Online (Sandbox Code Playgroud)
这是我想调用的简单函数:
func changeBackButton() {
withAnimation {
showBackButton = false
isEditing = true
}
}
Run Code Online (Sandbox Code Playgroud)
任何指导将不胜感激。Xcode 13.2.1 iOS 15
小智 9
为什么不直接使用计算变量呢?
@State private var something: Int = 1
@State private var another: Bool = true
@State private var yetAnother: String = "whatever"
var anyOfMultiple: [String] {[
something.description,
another.description,
yetAnother
]}
var body: some View {
VStack {
//
}
.onChange(of: anyOfMultiple) { _ in
//
}
}
Run Code Online (Sandbox Code Playgroud)
我们扩展该Binding
类型以创建两个新方法,这两个方法都称为onChange
.
这两种onChange
方法都适用于每当Binding
实例的wrappedValue
属性通过其方法更改(而不仅仅是set)时您需要执行某些工作的情况set
。
第一个onChange
方法不会Binding
将实例属性的新值传递wrappedValue
给提供的更改回调方法,而第二个onChange
方法则为其提供新值。
第一种onChange
方法允许我们重构它:
bindingToProperty.onChange { _ in
changeBackButton()
}
Run Code Online (Sandbox Code Playgroud)
对此:
bindingToProperty.onChange(perform: changeBackButton)
Run Code Online (Sandbox Code Playgroud)
import SwiftUI
extension Binding {
public func onChange(perform action: @escaping () -> Void) -> Self where Value : Equatable {
.init(
get: {
self.wrappedValue
},
set: { newValue in
guard self.wrappedValue != newValue else { return }
self.wrappedValue = newValue
action()
}
)
}
public func onChange(perform action: @escaping (_ newValue: Value) -> Void) -> Self where Value : Equatable {
.init(
get: {
self.wrappedValue
},
set: { newValue in
guard self.wrappedValue != newValue else { return }
self.wrappedValue = newValue
action(newValue)
}
)
}
}
Run Code Online (Sandbox Code Playgroud)
struct EmployeeForm: View {
@ObservedObject var vm: VM
private func changeBackButton() {
print("changeBackButton method was called.")
}
private func occupationWasChanged() {
print("occupationWasChanged method was called.")
}
var body: some View {
Form {
TextField("First Name", text: $vm.firstName.onChange(perform: changeBackButton))
TextField("Last Name", text: $vm.lastName.onChange(perform: changeBackButton))
TextField("Occupation", text: $vm.occupation.onChange(perform: occupationWasChanged))
}
}
}
struct Person {
var firstName: String
var surname: String
var jobTitle: String
}
extension EmployeeForm {
class VM: ObservableObject {
@Published var firstName = ""
@Published var lastName = ""
@Published var occupation = ""
func load(from person: Person) {
firstName = person.firstName
lastName = person.surname
occupation = person.jobTitle
}
}
}
struct EditEmployee: View {
@StateObject private var employeeForm = EmployeeForm.VM()
@State private var isLoading = true
func fetchPerson() -> Person {
return Person(
firstName: "John",
surname: "Smith",
jobTitle: "Market Analyst"
)
}
var body: some View {
Group {
if isLoading {
Text("Loading...")
} else {
EmployeeForm(vm: employeeForm)
}
}
.onAppear {
employeeForm.load(from: fetchPerson())
isLoading = false
}
}
}
struct EditEmployee_Previews: PreviewProvider {
static var previews: some View {
EditEmployee()
}
}
Run Code Online (Sandbox Code Playgroud)
Binding
接近向TextField/TextEditor/其他类型提供实例的位置。Binding
实例。wrappedValue
Equatable
Binding
具有更改回调的实例看起来就像没有Binding
更改回调的实例。因此,没有向这些Binding
具有更改回调的实例提供任何类型,需要进行特殊修改才能知道如何处理它们。View
、@State
属性、、、、ObservableObject
或任何其他类型。它只是向名为的现有类型添加了几个方法- 这显然是一种已经在代码中使用的类型......EnvironmentKey
PreferenceKey
Binding
归档时间: |
|
查看次数: |
7224 次 |
最近记录: |