SwiftUI by Apple | Wrap-up: Layout and Style — Part 2.4

Tony Trejo
3 min readJul 30, 2024

--

SwiftUI by Apple | Wrap-up: Bringing It All Together — Part 2.4

🚀 #6.5 Excited to Share Wrap-up: Bringing It All Together! 🌟

This tutorial covers some essential SwiftUI topics like `@Binding` and `@State`.

🔗 Tutorial: Bringing It All Together

https://developer.apple.com/tutorials/sample-apps/layingoutviews#Bringing-it-all-together

📌 Topic: Wrap-up — Bringing It All Together

📝 Subtopics:

- State:

📚 https://developer.apple.com/documentation/swiftui/state

A property wrapper type that can read and write a value managed by SwiftUI.

It’s possible to store an object that conforms to the `ObservableObject` protocol in a `State` property. However, the view will only update when the reference to the object changes.

To track changes to both the reference and the object’s published properties, use `StateObject` instead of `State`.

Diagrams:

Using `@State` vs. `@StateObject`

Using @State                      Using @StateObject
+-----------------------+ +-----------------------+
| ParentView | | ParentView |
|-----------------------| |-----------------------|
| - @State | | - @StateObject |
| viewModel: MyModel | | viewModel: MyModel |
| | | |
| +-----------------+ | | +-----------------+ |
| | ChildView | | | | ChildView | |
| | (viewModel: | | | | (viewModel: | |
| | $viewModel) | | | | viewModel) | |
| | | | | | | |
| | Passes Binding | | | | Passes Reference| |
| +-----------------+ | | +-----------------+ |
| | | |
+-----------------------+ +-----------------------+
| |
v v
+-----------------------+ +-----------------------+
| ChildView | | ChildView |
|-----------------------| |-----------------------|
| - @Binding | | - @ObservedObject |
| viewModel: MyModel | | viewModel: MyModel |
| | | |
| // Use viewModel | | // Use viewModel |
+-----------------------+ +-----------------------+

When to Use:

Use `@State`:

- Purpose: Manages simple, value-type state within a single view.

- When to Use:

- When the child view needs to modify the entire object but doesn’t need to react to changes within the object.

- When you have simple, local state (e.g., a boolean for a toggle, a string for a text field) that doesn’t need to be shared with other views.

- When you need to create a binding for primitive types or small, immutable objects.

- When the state changes do not involve complex data structures or objects.

Use `@StateObject`:

- Purpose: Manages complex, reference-type state (i.e., objects conforming to `ObservableObject`) within a view.

- When to Use:

- When the child view needs to both modify the object and react to changes within the object.

- When you need to manage state in an object that has multiple properties and the properties can change independently.

- When you need to ensure the view updates in response to changes within the `ObservableObject`’s `Published` properties.

- When you initialize the object within the view itself and want SwiftUI to manage its lifecycle.

Binding:

📚 https://developer.apple.com/documentation/swiftui/binding)

A property wrapper type that can read and write a value owned by a source of truth. Use a binding to create a two-way connection between a property that stores data.

Diagram: Using `@State` with `@Binding`

+-------------------------------+         
| PlayerParentView |
|-------------------------------|
| - @State |
| isPlaying: Bool = false |
| |
| +-------------------------+ |
| | PlayChildButton |
| | (isPlaying: $isPlaying) | <-- Binding creation using $
| +-------------------------+ |
| |
+-------------------------------+
                  |
| $isPlaying creates a Binding
v
+-------------------------------+
| PlayChildButton |
|-------------------------------|
| - @Binding |
| isPlaying: Bool |
| |
| +------------------------+ |
| | Button(isPlaying ? | |
| | "Pause" : "Play") | |
| | { | |
| | isPlaying.toggle() | | <-- Toggles state
| | } | |
| +------------------------+ |
+-------------------------------+

In short, `@State` manages the state in the parent view, while `@Binding` allows child views to interact with that state. Whenever the user taps the `PlayChildButton`, the `PlayerParentView` updates its `isPlaying` state.

Other SwiftUI Concepts:

- Button

A control that initiates an action.

📚 https://developer.apple.com/documentation/swiftui/button

- ForEach

A structure that computes views on demand from an underlying collection of identified data.

📚 https://developer.apple.com/documentation/swiftui/foreach

Modifiers:

- `shadow(_:width:)`: Adds a shadow to this view.

📚https://developer.apple.com/documentation/swiftui/view/shadow(color:radius:x:y:)

- `cornerRadius(_:antialiased:)`: Clips this view to its bounding frame, with the specified corner radius.

📚 https://developer.apple.com/documentation/swiftui/view/overlay(_:alignment:)

Final Thoughts:

The documentation contains many great examples, but as developers, we often need to dive into the details to ensure correct implementation. If something isn’t working as expected, it might be because we’re not using it the right way.

#dev #development #ios

--

--