Forked from RuiAAPeres/SwiftUI Property Delegates.swift
Created
June 21, 2019 03:40
-
-
Save vinhnx/3f47717310986403d3bfd8cf8ddb966e to your computer and use it in GitHub Desktop.
This file contains 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
/// `ObjectBinding` used as a way to create a `Binding` from a `BindableObject`. In this case the ViewModel | |
/// complies with `BindableObject` which is then translated into a `Binding` which is what `Toggle` is expecting | |
/// NOTE: Since it's a `DynamicViewProperty`, after its value is changed, the body will be updated. | |
class ViewModel: BindableObject { | |
let didChange = PassthroughSubject<ViewModel, Never>() | |
var isEnabled = false { | |
didSet { | |
didChange.send(self) | |
} | |
} | |
} | |
struct ObjectBinding_ExampleView : View { | |
@ObjectBinding(initialValue: ViewModel()) var viewModel: ViewModel | |
var body: some View { | |
Toggle(isOn: $viewModel.isEnabled) { | |
Text("The value is " + "\(viewModel.isEnabled)") | |
} | |
} | |
} | |
/// ================================== | |
/// `State` used as a quick way to store a mutable, bindable entity. | |
/// NOTE: Since it's a `DynamicViewProperty`, after its value is changed, the body will be updated. | |
struct State_ExampleView : View { | |
@State var value: Bool | |
var body: some View { | |
Toggle(isOn: $value) { | |
Text("The value is " + "\($value)") | |
} | |
} | |
} | |
/// ================================== | |
/// `Environment` used to get values from `EnvironmentValues`. These range from `Calendar` to `ColorScheme`, `Fonts`, `Locale` | |
/// and others | |
struct ContentView : View { | |
@Environment(\.isEnabled) var enabled: Bool | |
var body: some View { | |
Text("The value is " + "\(enabled)") | |
} | |
} | |
/// ================================== | |
/// `@EnvironmentObject` acts like a DI Container for Binds. You can register anything that conforms to `Bindable` via | |
/// `.environmentObject` and use `@EnvironmentObject` to read that value from the container. | |
/// NOTE: Since it's a `DynamicViewProperty`, after its value is changed, the body will be updated. | |
class ViewModel: BindableObject { | |
let didChange = PassthroughSubject<ViewModel, Never>() | |
var isEnabled = false { | |
didSet { | |
didChange.send(self) | |
} | |
} | |
} | |
struct ContentView : View { | |
@EnvironmentObject var viewModel: ViewModel | |
var body: some View { | |
Toggle(isOn: $viewModel.isEnabled) { | |
Text("The value is " + "\(viewModel.isEnabled)") | |
} | |
} | |
} | |
/// You create the ContentView and associate the type | |
/// The `var viewModel` is set automatically for you. | |
let view = ContentView().environmentObject(ViewModel()) | |
/// ================================== | |
/// `Binding` is a wraper for a setter and a getter. It's the `@ObjectBinding` in this case that kicks the view | |
/// renderization. | |
class ViewModel: BindableObject { | |
let didChange = PassthroughSubject<ViewModel, Never>() | |
var textInput = "" { | |
didSet { | |
didChange.send(self) | |
} | |
} | |
} | |
struct ContentView : View { | |
@ObjectBinding var viewModel: ViewModel | |
init(viewModel: ViewModel) { | |
self.viewModel = viewModel | |
} | |
var body: some View { | |
List { | |
Text("email") | |
TextField(viewModel[\.textInput]) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment