Forked from neilsmithdesign/swift-ui-protocol-view-models.swift
Created
March 20, 2023 14:58
-
-
Save msuzoagu/751162b94c60961c573584c24004e6ba 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