<!--
{
  "availability" : [
    "iOS: 13.0.0 -",
    "iPadOS: 13.0.0 -",
    "macCatalyst: 13.0.0 -",
    "macOS: 10.15.0 -",
    "tvOS: 13.0.0 -",
    "visionOS: 1.0.0 -",
    "watchOS: 6.0.0 -"
  ],
  "documentType" : "symbol",
  "framework" : "SwiftUI",
  "identifier" : "/documentation/SwiftUI/ViewModifier",
  "metadataVersion" : "0.1.0",
  "role" : "Protocol",
  "symbol" : {
    "kind" : "Protocol",
    "modules" : [
      "SwiftUI"
    ],
    "preciseIdentifier" : "s:7SwiftUI12ViewModifierP"
  },
  "title" : "ViewModifier"
}
-->

# ViewModifier

A modifier that you apply to a view or another view modifier, producing a
different version of the original value.

```
@MainActor @preconcurrency protocol ViewModifier
```

## Overview

Adopt the [`ViewModifier`](/documentation/SwiftUI/ViewModifier) protocol when you want to create a reusable
modifier that you can apply to any view. The example below combines several
modifiers to create a new modifier that you can use to create blue caption
text surrounded by a rounded rectangle:

```
struct BorderedCaption: ViewModifier {
    func body(content: Content) -> some View {
        content
            .font(.caption2)
            .padding(10)
            .overlay(
                RoundedRectangle(cornerRadius: 15)
                    .stroke(lineWidth: 1)
            )
            .foregroundColor(Color.blue)
    }
}
```

You can apply [`modifier(_:)`](/documentation/SwiftUI/View/modifier(_:)) directly to a view, but a more common
and idiomatic approach uses [`modifier(_:)`](/documentation/SwiftUI/View/modifier(_:)) to define an extension to
[`View`](/documentation/SwiftUI/View) itself that incorporates the view modifier:

```
extension View {
    func borderedCaption() -> some View {
        modifier(BorderedCaption())
    }
}
```

You can then apply the bordered caption to any view, similar to this:

```
Image(systemName: "bus")
    .resizable()
    .frame(width:50, height:50)
Text("Downtown Bus")
    .borderedCaption()
```

![A screenshot showing the image of a bus with a caption reading](images/com.apple.SwiftUI/SwiftUI-View-ViewModifier@2x.png)

A type conforming to this protocol inherits `@preconcurrency @MainActor`
isolation from the protocol if the conformance is included in the type’s
base declaration:

```
struct MyCustomType: Transition {
    // `@preconcurrency @MainActor` isolation by default
}
```

Isolation to the main actor is the default, but it’s not required. Declare
the conformance in an extension to opt out of main actor isolation:

```
extension MyCustomType: Transition {
    // `nonisolated` by default
}
```

## Topics

### Creating a view modifier

[`body(content:)`](/documentation/SwiftUI/ViewModifier/body(content:))

Gets the current body of the caller.

[`Body`](/documentation/SwiftUI/ViewModifier/Body)

The type of view representing the body.

[`ViewModifier.Content`](/documentation/SwiftUI/ViewModifier/Content)

The content view type passed to `body()`.

### Adding animations to a view

[`animation(_:)`](/documentation/SwiftUI/ViewModifier/animation(_:))

Returns a new version of the modifier that will apply
`animation` to all animatable values within the modifier.

[`concat(_:)`](/documentation/SwiftUI/ViewModifier/concat(_:))

Returns a new modifier that is the result of concatenating
`self` with `modifier`.

### Handling view taps and gestures

[`transaction(_:)`](/documentation/SwiftUI/ViewModifier/transaction(_:))

Returns a new version of the modifier that will apply the
transaction mutation function `transform` to all transactions
within the modifier.



---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)