I'm reading SwiftUI materials and it's said that view modifiers for example:
struct ByeView: View {
var body: some View {
Text("Bye bye, world!")
.font(.headline)
}
}
creates a new view with .headline
font and returns the view.
So I wonder if it's more like:
func font(_ font: UIFont) -> Text {
Text(text, font: font)
}
rather than:
func font(_ font: UIFont) -> Text {
self.font = font
return self
}
I feel for event modifiers, since they may not have to modify the view, there's no need to "create a new view with modified aspects", but not sure about the modifiers that do adjust the views.
Thanks!
CodePudding user response:
First, note that an implementation such as
func font(_ font: UIFont) -> Text {
self.font = font
return self
}
does not compile. font
would need to be mutating
for this to work, but it isn't mutating
. That said, this would have compiled:
self.someReferenceType.font = font
But this has another problem. This means that font
now has a side effect:
var body: some View {
let x = Text("foo")
x.font(.headline)
return x // this should have non-headline font, but if the
// implementation above were used, it would have headline font
}
So I think it is very likely that the actual implementation involves calling the initialiser, rather than return self
. This also matches the wording in the documentation's wording that a "new view" is "created".
For modifiers that return some View
, you can check the type they return using type(of:)
. You will most likely see that the type they return is different from self
, which means they definitely do not return self
! After all, that's one of the reasons why the opaque type some View
is used in the signature - to hide the internal types Apple used to implement these modifiers.
// doesn't work in a playground for some reason
// make a .swift file, compile and run
let x = Text("foo").onAppear {}
print(type(of: x))
For me, this prints: ModifiedContent<Text, _AppearanceActionModifier>
, not Text
, so clearly a new view is created here. (See also ModifiedContent
)
CodePudding user response:
TLDR
We can't know for sure as the implementation detail is hidden.
My point of view
I might be wrong but I think it's possible that neither of modifying an instance of a View or assigning to a property that you have described are actually happening, but we can't know for sure since the implementation is private.
Since SwiftUI is a declarative framework, where you describe what you want to get and the OS takes care of that, it could be even that by writing:
SomeView()
.padding()
.background(Color.red)
.cornerRadius(8)
Internally it could become just about any representation such as JSON that the parser could read.
Essentially no instance of any object (apart from the description) representing a View, Color or CornerRadius could exist before its initialization based on the description and current state, thus there would be no instance holding properties (such as font) that could be assigned or altered before the final View is initialized.