我正在使用swiftUI进行合并,我的VM中具有一些业务逻辑。有些结果不得不驳斥我的观点。
我在某些视图中使用过这个:
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
self.presentationMode.wrappedValue.dismiss()
我想要在视图模型中使用类似的东西。
答案 0 :(得分:1)
您不会在SwiftUI
中以命令方式进行解雇。取而代之的是,您通过将.sheet
视图绑定到一个布尔属性来使用该视图,该布尔属性将从该视图模型中发生变化。
在回答后续问题之后 question, 我想出了另一种方法。如果解雇是很不错的 实际上需要从模态呈现的
View
内部完成 本身。
您可以通过实现自定义Publisher
来实现此目的,该自定义.send()
将使用View
方法来允许您将特定值发送给订户(在这种情况下为onReceive(_:perform:)
)。您将使用在 SwiftUI 的View
协议上定义的Publisher
方法来订阅您定义的自定义perform
的输出流。在View
动作闭包内,您将可以访问{{1}。
有足够的理论,您可以看一下下面的代码,应该不会很难理解:
import Foundation
import Combine
class ViewModel: ObservableObject {
var viewDismissalModePublisher = PassthroughSubject<Bool, Never>()
private var shouldDismissView = false {
didSet {
viewDismissalModePublisher.send(shouldDismissView)
}
}
func performBusinessLogic() {
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.shouldDismissView = true
}
}
}
与之对应的观点是:
import SwiftUI
struct ContentView: View {
@State private var isDetailShown = false
var body: some View {
VStack {
Text("Hello, World!")
Button(action: {
self.isDetailShown.toggle()
}) {
Text("Present Detail")
}
}
.sheet(isPresented: $isDetailShown) {
DetailView()
}
}
}
struct DetailView: View {
@ObservedObject var viewModel = ViewModel()
@Environment(\.presentationMode) private var presentationMode
var body: some View {
Text("Detail")
.navigationBarTitle("Detail", displayMode: .inline)
.onAppear {
self.viewModel.performBusinessLogic()
}
.onReceive(viewModel.viewDismissalModePublisher) { shouldDismiss in
if shouldDismiss {
self.presentationMode.wrappedValue.dismiss()
}
}
}
}
关于视图模型中业务逻辑更改的视图解除的一个非常简单的实现是:
struct ContentView: View {
@ObservedObject var viewModel = ViewModel()
var body: some View {
Text("Hello, World!")
// the animation() modifier is optional here
.sheet(isPresented: $viewModel.isSheetShown.animation()) {
Text("Sheet Presented")
}
// From here - for illustration purpose
.onAppear {
self.viewModel.perform()
}
// To here
}
}
class ViewModel: ObservableObject {
@Published var isSheetShown = false
func perform() {
// this just an example. In real application, you will be responsible to
// toggle between the states of the `Bool` property
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.isSheetShown.toggle()
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.isSheetShown.toggle()
}
}
}
}