Passing Data in SwiftUI

Jun 20 2024 · Swift 5.9, iOS 17.2, Xcode 15.2

Lesson 02: Implementing Data Passing Techniques

Demo: Simplifying Data Management with SwiftUI Environment

Episode complete

Play next episode

Next

Heads up... You’re accessing parts of this content for free, with some sections shown as obfuscated text.

Heads up... You’re accessing parts of this content for free, with some sections shown as obfuscated text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

Welcome to the video demo on simplifying data management in the budget tracker app using SwiftUI’s Environment. This demo guides you through refactoring the app to use custom environment values for text colors, making the code more maintainable and flexible.

Step 1: Define Custom Environment Keys

In this step, you’ll define custom Environment keys for managing text colors in the SwiftUI Environment. Follow these detailed instructions:

Step 1.1: Create ExpenseTextColorKey

First, create an Environment key for the expense text color:

struct ExpenseTextColorKey: EnvironmentKey {
  static let defaultValue: Color = .red
}

Step 1.2: Create IncomeTextColorKey

Next, define an Environment key for the income text color:

struct IncomeTextColorKey: EnvironmentKey {
  static let defaultValue: Color = .green
}

Step 1.3: Add expenseTextColor to EnvironmentValues

Now, extend EnvironmentValues to include the property for the expense text color:

extension EnvironmentValues {
  var expenseTextColor: Color {
    get { self[ExpenseTextColorKey.self] }
    set { self[ExpenseTextColorKey.self] = newValue }
  }
}

Step 1.4: Add incomeTextColor to EnvironmentValues

Next, add the property for the income text color to the same extension:

extension EnvironmentValues {
  // ...

  var incomeTextColor: Color {
    get { self[IncomeTextColorKey.self] }
    set { self[IncomeTextColorKey.self] = newValue }
  }
}

Step 2: Apply Custom Environment Values

Now, adjust the FinancialEntryRow view to use the newly created Environment values instead of hard-coded colors.

struct FinancialEntryRow: View {
  // ...

  @Environment(\.expenseTextColor)
  var expenseTextColor: Color
  @Environment(\.incomeTextColor)
  var incomeTextColor: Color

  // ...
}
struct FinancialEntryRow: View {
  // ...

  var body: some View {
    HStack {
      // ...
      Text("$\(entry.amount, specifier: "%.2f")")
        .foregroundColor(entry.isExpense ?
          expenseTextColor : incomeTextColor)
    }
  }
}

Step 3: Testing the Changes

It’s time to test the modifications:

Step 4: Overriding Environment Values in SwiftUI

In the previous steps, you defined custom Environment values in the budget tracker app. Now, explore how to override these values for specific views. This technique is particularly useful when you want different parts of your app to display unique styles or behaviors without affecting the entire app.

ForEach(entries) { entry in
  FinancialEntryRow(entry: entry)
}
ForEach(entries) { entry in
  FinancialEntryRow(entry: entry)
    .environment(\.expenseTextColor, .orange)
}

Additional Note on Historical Context

As you continue exploring SwiftUI and perhaps look at other resources or older projects, you might come across older SwiftUI data-flow tools used before iOS 17 such as @EnvironmentObject. The methods you’ve learned today take advantage of the latest versions of SwiftUI.

Wrapping Up the Video Demo

Congratulations! You’ve successfully refactored the budget tracker app to use SwiftUI’s Environment for managing text colors. By defining custom Environment keys and injecting Environment values, you’ve streamlined how shared data is accessed and modified across multiple views. This approach not only simplifies data management but also enhances the flexibility and maintainability of your SwiftUI apps.

Transition to Lesson Conclusion

Now that you have a solid foundation in implementing data-passing techniques in SwiftUI apps, it’s time to conclude this lesson by summarizing the key points.

See forum comments
Cinema mode Download course materials from Github
Previous: Introducing the SwiftUI Environment Next: Conclusion