Custom Property Wrappers

Bundle reusable get/set behaviour into a type with @propertyWrapper . Learn the required wrappedValue , the projectedValue behind the $ prefix, custom initializers, and why @State , @Published , and @Binding are all property wrappers.

Learn Custom Property Wrappers in our free Swift course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…

Part of the free Swift course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

What You'll Learn in This Lesson

1️⃣ Your First Wrapper

Mark a type @propertyWrapper and give it a wrappedValue . Making wrappedValue a computed property lets you run logic — here, clamping — on every write.

2️⃣ projectedValue and the $ Prefix

A wrapper can publish an extra value via projectedValue . You reach it with the $ prefix on the wrapped property — separate from wrappedValue .

3️⃣ A Practical Wrapper: UserDefault

Because a wrapper is a normal type, it can store state and reach external systems. This generic UserDefault persists each write automatically.

Your turn. Fill in the defining attribute and the required property name.

4️⃣ Wrappers You Already Use

SwiftUI's state tools are property wrappers. @State owns value-type state and projects a Binding through $ ; @Binding shares a source of truth; @Published projects a Combine publisher.

📋 Quick Reference

Write a wrapper that capitalizes every word it stores, then apply it to a title property.

Practice quiz

Which attribute marks a type as a property wrapper?

  • @propertyWrapper
  • @property
  • @wrapped
  • @wrapper

Answer: @propertyWrapper. A type becomes a property wrapper when you mark it with the @propertyWrapper attribute.

Which member is REQUIRED for a property wrapper to compile?

  • init()
  • description
  • wrappedValue
  • projectedValue

Answer: wrappedValue. Every property wrapper must expose a wrappedValue property; everything else is optional.

When you write @Clamped var x, what is x's type as seen by the user?

  • Always Int
  • The type of wrappedValue
  • Optional
  • The wrapper type

Answer: The type of wrappedValue. Accessing the wrapped property reads and writes through wrappedValue, so x has wrappedValue's type.

What does the $ prefix on a wrapped property give you?

  • The raw storage
  • A force-unwrap
  • The wrapper's init
  • The projectedValue

Answer: The projectedValue. The $ prefix exposes the wrapper's projectedValue, an extra value the wrapper chooses to publish.

In SwiftUI, what does @State actually provide under the hood?

  • A property wrapper managing view-owned mutable state
  • A computed property
  • A singleton
  • A global variable

Answer: A property wrapper managing view-owned mutable state. @State is a property wrapper that stores value-type state owned and tracked by the view.

For @Binding var name, what does $name give you in SwiftUI?

  • A new copy
  • A Binding<String> projectedValue
  • Nothing
  • A String

Answer: A Binding<String> projectedValue. @Binding projects a Binding so child views can read and write the source of truth via $name.

How does a wrapper run code when a value is assigned?

  • Using a global hook
  • With a deinit
  • It cannot
  • By making wrappedValue a computed property with a setter

Answer: By making wrappedValue a computed property with a setter. Defining wrappedValue as a computed property lets the get and set run custom logic on every access.

Which initializer does the compiler call for @Wrapper var v = 5?

  • init(projectedValue:)
  • init(value:)
  • init(wrappedValue:)
  • init()

Answer: init(wrappedValue:). An assigned default value is forwarded to init(wrappedValue:) when that initializer exists.

What is @Published from Combine an example of?

  • A result builder
  • A property wrapper that announces changes via a publisher
  • A macro
  • A protocol

Answer: A property wrapper that announces changes via a publisher. @Published is a property wrapper whose projectedValue is a Combine publisher that emits on change.

Can a property wrapper add stored properties of its own?

  • Yes, it is a normal type that can store state
  • Only with macros
  • No, never
  • Only computed ones

Answer: Yes, it is a normal type that can store state. A wrapper is an ordinary struct or class, so it can hold its own stored properties for backing storage.