Fernando Olivares

August 9, 2023

What is a View?

I obviously understand what is a View. In its most technical sense, a View is a protocol that has an associated type body which conforms to View. The interesting part of the question is, is a View still a View when you modify it?

For example, a Text View that has its opacity reduced, is it still a View?

Well, yes. If the question asked is, is it still a View? The answer is a resounding yes.

What if the question asked was, is a Text still a Text if its opacity is reduced?

And funnily enough, the answer is no. It stops being a text. It's actually pretty easy to test.

Screenshot 2023-08-08 at 18.02.54.png


It is perhaps a bit convoluted, but I'm still using that ExampleView for testing my assumptions. For now, when printing the type of exampleMirror, we'll get:

ModifiedContent<Text, _OpacityEffect>.Type

And that's very interesting to me! What exactly is ModifiedContent? I originally could not find it via quick open, which is interesting. However, diving directly into the SwiftUI library declarations, we find that ModifiedContent is just a struct that contains two generic values: the content and the modified value. In the above example then (emphasis mine):

ModifiedContent<Text (content), _OpacityEffect (modifier)>.Type
 
The Text is the content and OpacityEffect is a modifier. The documentation of ModifiedContent is also very helpful:

/// If `content` is a ``View`` and `modifier` is a ``ViewModifier``, the
/// result is a ``View``. If `content` and `modifier` are both view
/// modifiers, then the result is a new ``ViewModifier`` combining them.

TIL! This would explain the whole SwiftUI system if Content and ViewModifier both conform to View? In the end, we eventually want to end up with a View, right? Even when modifying content.

ViewModifier was easy to find. It's a protocol whose eventual result should be a View. It can be concatenated or transformed using other ViewModifiers, but we obviously want to end up as a View at some point.

Content was more difficult to find. Content appears to be a typealias defined in ViewModifier, but a typealias for what? Note that Content is everywhere in the SwiftUI library, so I searched for it for a couple of minutes until I found this great SwiftUI answer by Rob Mayoff. Go and read that then come back.

Interesting, isn't it? I was correct in my assumption that both Content and ViewModifier should both conform to view. Well, sort of. ViewModifier doesn't necessarily need to conform to View, but it needs to return a View at some point. We can't keep returning ViewModifiers because they're not Views. 

So, how can I summarize this? The easiest way to summarize this is that I hated using Core Data because it was opaque and had some magic-y rules. SwiftUI is like that but worse, with a lot of it hidden behind the scenes. I understand the advantages of it (just write it and we'll deal with the difficulties of rendering your content), but I also understand the disadvantages (how does this work? 🧙🏻‍♂️).

Anyway, for now, I understand that when the body says some View, it really is some View. It's Views all the way down (sprinkled with ViewModifiers).