Forked from neilsmithdesign/swift-ui-protocol-view-models.swift
Created
March 12, 2022 14:49
-
-
Save takiguri/85da4f2231bd6c16d9d6eca6274261f6 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