📜  添加回调以查看 swiftui - Swift (1)

📅  最后修改于: 2023-12-03 14:56:07.462000             🧑  作者: Mango

添加回调以查看 SwiftUI - Swift

SwiftUI是一种现代的声明式UI框架,可以用于构建跨平台的应用程序。在SwiftUI中,回调是一种机制,可用于添加用户交互和实现数据流。在该主题中,我们将探讨如何添加回调以查看SwiftUI。

添加回调

SwiftUI中添加回调可以通过在视图中使用(@State,@Binding,@EnvironmentObject) 、 ObservableObject或者闭包的方式实现。具体取决于您要为哪个方面添加回调。

在视图中使用@State,@Binding

我们可以在视图中使用@State@Binding来添加回调。通常情况下,我们使用@State为单个组件保存状态,并使用@Binding将其传递给其他组件,以实现其中一个组件的状态更改。

例如,假设您有以下计数器组件:

struct CounterView: View {
    @State private var counter = 0

    var body: some View {
        Button(action: {
            self.counter += 1
        }) {
            Text("Count: \(counter)")
        }
    }
}

现在,假设您想要在每次计数器达到特定值时调用回调。您可以通过添加闭包来实现。在以下示例中,您可以看到如何在计数器达到5时调用回调:

struct CounterView: View {
    typealias CounterCallback = () -> Void
    @State private var counter = 0

    let counterCallback: CounterCallback
    
    init(counterCallback: @escaping CounterCallback) {
        self.counterCallback = counterCallback
    }

    var body: some View {
        Button(action: {
            self.counter += 1
            if self.counter == 5 { self.counterCallback() }
        }) {
            Text("Count: \(counter)")
        }
    }
}

现在您可以调用CounterView时添加回调:

let counterView = CounterView {
    print("Counter reached 5!")
}
使用ObservableObject

您可以使用ObservableObject类来添加回调以管理整个视图,而不是只是单个组件。您可以将ObservableObject类与@ObservedObject属性包装器结合使用,以通知更改,并在需要时调用回调。

例如,假设您有以下简单应用程序:

class CounterModel: ObservableObject {
    @Published var counter = 0
}

struct ContentView: View {
    @ObservedObject var model = CounterModel()
    
    var body: some View {
        VStack {
            Text("Count: \(model.counter)")
            
            Button(action: {
                self.model.counter += 1
            }) {
                Text("Increment")
            }
        }
    }
}

您可以在CounterModel中添加回调,以在计数器达到特定值时调用。在以下示例中,当计时器达到5时,将调用回调:

class CounterModel: ObservableObject {
    typealias CounterCallback = () -> Void
    @Published var counter = 0

    let counterCallback: CounterCallback
    
    init(counterCallback: @escaping CounterCallback) {
        self.counterCallback = counterCallback
    }
    
    func increment() {
        counter += 1
        if counter == 5 { self.counterCallback() }
    }
}

struct ContentView: View {
    @ObservedObject var model: CounterModel
    
    init(model: CounterModel) {
        self.model = model
        self.model.counterCallback = self.handleCountReached
    }
    
    func handleCountReached() {
        print("Counter reached 5!")
    }

    var body: some View {
        VStack {
            Text("Count: \(model.counter)")
            
            Button(action: {
                self.model.increment()
            }) {
                Text("Increment")
            }
        }
    }
}

现在,当计数器达到5时,将调用回调。

使用闭包

最后,您可以使用闭包将回调添加到任何SwiftUI组件中。这是最灵活的方法,但也是最容易出错的方法,因此需要谨慎使用。

例如,以下是一个高阶组件OnCountReached,该组件可在计数器到达特定值时触发回调:

struct OnCountReached: ViewModifier {
    typealias CounterCallback = () -> Void
    let count: Int
    let counterCallback: CounterCallback
    
    func body(content: Content) -> some View {
        Button(action: {
            self.counterCallback()
        }) {
            content
        }.disabled(count != 5)
    }
}

extension View {
    func onCountReached(count: Int, perform: @escaping () -> Void) -> some View {
        self.modifier(OnCountReached(count: count, counterCallback: perform))
    }
}

现在,您可以使用onCountReached修饰符将回调添加到任何组件中:

Button("Increment") {
    self.count += 1
}.onCountReached(count: 5) {
    print("Counter reached 5!")
}

在这个示例中,当计数器达到5时,将调用回调。

结论

在SwiftUI中,回调是一种添加用户交互和实现数据流的强大机制。无论您使用@State,@Binding,@EnvironmentObjectObservableObject或闭包,回调都是一种方便和灵活的方法来检测和响应变化。在使用回调时,请务必小心,并确保您的代码保持可读且易于维护。