Last active
June 18, 2024 15:24
-
-
Save neilsmithdesign/115f892e921b97b115bfae3e038501d1 to your computer and use it in GitHub Desktop.
SwiftUI views with protocol interfaces to view models.
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 SwiftUI | |
/// View model protocol | |
protocol ViewModel: ObservableObject { | |
var count: Int { get } | |
func increase() | |
} | |
/// Concrete implementation | |
class MyViewModel: ViewModel { | |
@Published var count: Int = 0 | |
func increase() { | |
count += 1 | |
} | |
} | |
/// Alternative implementation | |
class MyOtherViewModel: ViewModel { | |
@Published var count: Int = 0 | |
func increase() { | |
count += 2 | |
} | |
} | |
/// View with generic parameter that is constrained to | |
/// the ViewModel protocol | |
struct MyView<VM>: View where VM: ViewModel { | |
// @ObservedObject var viewModel: ViewModel // <--- Compiler errors | |
@ObservedObject var viewModel: VM // <--- Compiler happy :) | |
var body: some View { | |
VStack(spacing: 20) { | |
Text("Count = \(viewModel.count)") | |
Button(action: { | |
self.viewModel.increase() | |
}) { | |
Text("Increase") | |
} | |
} | |
} | |
} | |
struct MyView_Preview: PreviewProvider { | |
static var previews: some View { | |
HStack { | |
MyView(viewModel: MyViewModel()) | |
Spacer() | |
MyView(viewModel: MyOtherViewModel()) | |
}.padding() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Saved me a lot of headache there, Thanks 🙌