Understanding SwiftUI Modifiers
Tags: swift, swiftui, ios
Published: 2020-10-29 17:27:59

A major paradigm shift is in progress in the Apple development world. For years, we were used to the imperative programming style of UIKit and AppKit. Even though there were many attempts by third parties with different styles, this imperative style of UI frameworks remained the same and most developers liked it.

When Apple introduced SwiftUI in 2019, the future looked distinctly different. It’s all declarative now. Not everyone was ready to jump in from the onset, but for those who dove into SwiftUI, it is a fun if occasionally frustrating journey. With [the improvements SwiftUI got in 2020](https://www.hackingwithswift.com/articles/221/whats-new-in-swiftui-for-ios-14), more developers are set to begin their journey with a declarative UI framework.

Let’s try to explore the workings of one of the most important parts of SwiftUI: modifiers.

A `View` can have any number of modifiers. They can be added to the view just like you would chain multiple function calls. Each modifier returns a `View` that the succeeding modifier will act on. Hence, when working with modifiers, the order in which you add them is really important. Let’s look at that with an example:

```
Image(systemName: "camera.fill")
    .padding(EdgeInsets(top: 10.0, leading: 10.0, bottom: 10.0, trailing: 10.0))
    .background(Color.green)
    .cornerRadius(10.0)
    .padding(EdgeInsets(top: 10.0, leading: 10.0, bottom: 10.0, trailing: 10.0))
    .background(Color.red)
    .rotationEffect(Angle(degrees: 15.0))
```

![Fully rotated view](https://dev-to-uploads.s3.amazonaws.com/i/kea3qknbdt5c5zjgdj9c.png)

As you can see from the code and preview above, `cornerRadius` is applied to the inner rectangle and the whole view is rotated, as the `rotationEffect` modifier is the last. Now let’s change the order of the modifiers:

```
Image(systemName: "camera.fill")
    .padding(EdgeInsets(top: 10.0, leading: 10.0, bottom: 10.0, trailing: 10.0))
    .background(Color.green)
    .rotationEffect(Angle(degrees: 15.0))
    .padding(EdgeInsets(top: 10.0, leading: 10.0, bottom: 10.0, trailing: 10.0))
    .background(Color.red)
    .cornerRadius(10.0)
```

![Rounded image](https://dev-to-uploads.s3.amazonaws.com/i/mhj9pfu45tn6vj6u6ejs.png)

We’ve now interchanged the positions of `rotationEffect` and `cornerRadius`. You can observe the difference in the resulting view. The inner rectangle is now rotated and the outer rectangle is rounded.

In these two examples, we’ve applied `background` and `padding` modifiers more than once. Each time, they modified the view. Now let’s explore another set of modifiers.

![Applying same modifer multiple times](https://dev-to-uploads.s3.amazonaws.com/i/x400ph5tcgft2qvdf02y.png)
*Can you tell how these modifiers are different from what we have seen above?*

In some cases, when you apply the same modifier twice, SwiftUI only takes the first one. This is clearly demonstrated by the `foregroundColor` modifier in the example above. This behavior is exactly opposite to how normal functions (and most of the SwiftUI modifiers) behave.

My understanding of this behavior is that when a modifier cannot have more than one effect on a view (e.g. any view can have only one foreground color), the one closest to the view is applied.

I was not able to find any documentation on why this is the case and which modifiers behave like this, but I’ve come to this understanding by working with SwiftUI for more than a year now.

How great would it be if Xcode provided us with a warning when adding such redundant modifiers more than once? Well, for that to happen, Xcode will need a SwiftUI compiler in addition to the existing Swift and Objective-C compilers.

But we can surely achieve these when we build apps that work with SwiftUI modifiers. When I first thought of [solving the problems I had when working with SF Symbols](https://dev.to/imthath_m/re-imagining-sf-symbols-into-xcode-2ol5), I envisioned a tool that does a better than job than the combined workflow of SF Symbols Mac app and Xcode.

[Swimbols](https://apps.apple.com/app/id1525226399?platform=ipad) lets you add modifiers instantly, edit or reorder modifiers to suit your needs and switch symbols with just a click after applying modifiers. All with real-time preview and you can copy the code when you are done.

When it doesn’t make sense for the modifier to be added more than once, Swimbols doesn’t show them in the list. And you can add as many of the other type of modifiers we discussed earlier in the post.

![Swimbols in action](https://dev-to-uploads.s3.amazonaws.com/i/65xl0f96l302t720peae.png)
*Swimbols in action - Add and edit modifiers, change symbols and preview instantly.*

You can play around with [Swimbols](https://apps.apple.com/app/id1525226399?platform=ipad) and visually reorder the modifiers to see how they affect the view instantly.

As SwiftUI improves, it is good to have a strong understanding of the basic building blocks. I hope it is now clear how the order of modifiers affects the view and why it doesn’t make sense for some modifiers to be used more than once.

Happy coding!