Skip to content

Instantly share code, notes, and snippets.

@iSevenDays
Last active October 12, 2021 10:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iSevenDays/8a0d58dee7e7bcb5b04d3e9d54b57a49 to your computer and use it in GitHub Desktop.
Save iSevenDays/8a0d58dee7e7bcb5b04d3e9d54b57a49 to your computer and use it in GitHub Desktop.
SwiftUI create View Model that emits close action
import Foundation
import Combine
import SwiftUI
/// View Model closable protocol - conform to this protocol if your view model should emit close block to close the screen that uses this view model
public protocol ViewModelClosableProtocol {
var closeCancellable: AnyCancellable? { get set }
// when inheriting protocol, set @Published
// var shouldCloseView: Bool { get set }
// @Published ~== CurrentValueSubject<Bool, Never>, but we can't use property wrappers in protocol
var shouldCloseView: CurrentValueSubject<Bool, Never> { get set }
}
extension ViewModelClosableProtocol {
mutating func closeAction() {
shouldCloseView.value = true
}
}
public protocol ViewWithPresentationMode {
var presentationMode: Binding<PresentationMode> { get }
}
public extension View where Self: ViewWithPresentationMode {
@inlinable func onAppearSetupCloseCallback<Closable: ViewModelClosableProtocol>(closableViewModel: inout Closable) {
closableViewModel.closeCancellable = closableViewModel.shouldCloseView.sink(receiveValue: { shouldClose -> Void in
if shouldClose {
presentationMode.wrappedValue.dismiss()
}
})
}
}
var SomeView: View, ViewWithPresentationMode {
var body: some View {
ZStack {
}.onAppear {
self.onAppearSetupCloseCallback(closableViewModel: &self.bussinessLogic.correctionDoseData)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment