I'm beginner in SwiftUI and I had some misunderstanding with the .frame() modifier.
I want to create a right-aligned image, so I'm doing this:
Image(systemName: "xmark")
.frame(maxWidth: .infinity, alignment: .leading)
.padding(5)
.background(.gray)
.mask(Circle())
.padding()
But the image appears in the center of my screen. I changed my code to this:
Image(systemName: "xmark")
.padding(5)
.background(.gray)
.mask(Circle())
.frame(maxWidth: .infinity, alignment: .leading)
.padding()
And it works the way I want it to, but I'm so confused as to why this code works. Can someone explain to me why this code works and the previous one doesn't?
I also see that people write code like that:
VStack {
...
}
.padding()
.frame(maxWidth: 200)
.frame(maxWidth: .infinity, alignment: .leading)
Does that even make sense? Aren't we redefining maxWidth with the second .frame() modifier?
CodePudding user response:
Yes, the position of the .frame()
modifier can affect the layout of the view in SwiftUI.
In your first example, the .frame(maxWidth: .infinity, alignment: .leading)
is applied before the other layout modifiers such as .padding(5), .background(.gray), .mask(Circle())
. So it sets the initial position and size of the image and the other layout modifiers are applied on top of that frame. Since the alignment is set to .leading
, the image is aligned to the leading edge but the alignment is relative to the frame set by the first .frame()
modifier, which is the whole screen.
In your second example, the .frame(maxWidth: .infinity, alignment: .leading)
is applied after the other layout modifiers. The other layout modifiers have already set the position and size of the image, and the second .frame(maxWidth: .infinity, alignment: .leading)
modifies the frame according to the alignment and maxWidth
, in this case, it makes the frame align to leading and take the whole width of the screen.
Regarding the third example, yes, it makes sense. The first .frame(maxWidth: 200)
sets a width of 200 for the VStack but the second .frame(maxWidth: .infinity, alignment: .leading)
overrides the maxWidth set by the first frame and aligns the VStack to leading and takes the whole width of the screen.
It's important to note that the order of the layout modifiers is important in SwiftUI and it can affect the final layout of the view. It's also important to understand that you can use multiple frame modifiers to achieve different effects.