swiftui · tutorial · security · components

Secure Container as a Reusable ViewModifier

Published October 22, 2026 · 3 min read · intermediate

Goal

By the end of this tutorial, you will have a reusable modifier that can wrap protected UI in one place. That keeps the feature boundary explicit and easier to reuse.

Requirements

  • Basic SwiftUI knowledge
  • Xcode 15+
  • A screen that needs a protected display region

The use case

This pattern appears when one feature has sensitive or protected content but you do not want that logic scattered across several views. Wrapping it into a modifier keeps the decision centralized.

Step 1 - Start with the content

Begin with the UI you want to protect.

import SwiftUI

struct SecureCard: View {
    var body: some View {
        Text("Protected content")
            .padding()
            .background(.thinMaterial)
    }
}

What changed:

  • the content is simple and readable
  • the protected region is obvious

Verification:

  • the view renders normally
  • the sensitive area is isolated

Step 2 - Extract the wrapper

Wrap the content in a reusable modifier.

struct SecureContainer: ViewModifier {
    func body(content: Content) -> some View {
        content
            .padding()
            .background(.thinMaterial)
    }
}

extension View {
    func secureContainer() -> some View {
        modifier(SecureContainer())
    }
}

What changed:

  • the secure styling is reusable
  • feature screens can apply the same boundary consistently

Verification:

  • any view can use .secureContainer()
  • the protected look stays identical

Step 3 - Apply it at the feature boundary

Use the modifier from the owning screen.

struct ProfileSecretsScreen: View {
    var body: some View {
        VStack {
            Text("Secret note")
                .secureContainer()
        }
    }
}

What changed:

  • the screen decides where the protected region lives
  • the modifier stays dumb and reusable

Verification:

  • the feature reads cleanly
  • the wrapper is easy to move or replace later

Result

You now have a reusable secure container that keeps the boundary in one place. That makes the feature easier to reason about and easier to update if the policy changes.

Common SwiftUI pitfalls

  • Mistake: putting feature logic inside the modifier
    Why it happens: the wrapper feels like a convenient home
    How to fix it: keep the modifier visual and structural only
  • Mistake: applying the modifier deep inside child views
    Why it happens: the child seems like the smallest place to put it
    How to fix it: apply the boundary where the feature is owned

When NOT to use this

Do not use a custom wrapper if the screen only needs one local style change. If the boundary is not reusable, a plain modifier is often clearer.

Takeaway

If you remember one thing: Reusable security boundaries should live at the feature edge, not buried in leaf views.

Next steps

This follows the same boundary logic as the other architecture posts in the catalog: