Last active
October 12, 2021 10:40
-
-
Save iSevenDays/8a0d58dee7e7bcb5b04d3e9d54b57a49 to your computer and use it in GitHub Desktop.
SwiftUI create View Model that emits close action
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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