Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

SwiftUI view centring behaviour on using new frame modifier

I have the following SwiftUI code:

    Rectangle()
        .fill(Color.blue.opacity(0.5))
        .frame(width: 130)
        .frame(maxWidth: .infinity)
        .background(Color.orange.opacity(0.5))
        .padding()
        .frame(maxHeight:100)

Here is the output.

enter image description here

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Clearly it can be seen that the inner rectangle in blue has been placed in the centre of outer rectangle. I tried experimenting with the alignment of frames and can see alignment of inner rectangle can only be changed by altering frame alignment of outer rect as follows:

  .frame(maxWidth: .infinity, alignment: .trailing)

But nothing changes if I change frame alignment property of inner rectangle.

I want to understand this behaviour more clearly — whether view is centred by default, and why inner frame alignment modification changes nothing.

>Solution :

The way layout works in SwiftUI is that parent views proposes a size to their children, and the children chooses how large they want to be, based on the proposal. Note that some views can ignore the proposal completely.

From the documentation, what frame(width:height:alignment:) does is,

Positions this view within an invisible frame with the specified size.

We can understand this as proposing a specific size to the view that frame is modifying. After the view chooses its size based on the proposal, it is aligned in the frame based on alignment. The default value of the alignment parameter is .center, so that’s why views are centered in the frame by default.

The way a Rectangle chooses its size, is that it resizes itself to the same size as the proposal (all Shapes behave like this). Therefore, it will always cover the entire frame you specified. This is why changing the alignment of the first frame modifier does not do anything – a view that covers the entire frame looks the same no matter how it is aligned inside the frame.

The frame(minWidth:idealWidth:maxWidth:minHeight:idealHeight:maxHeight:alignment:) modifier also positions the view it is modifying in a frame, but it gives the size proposal differently. It takes the size proposal it received from its parent, and clamps it to the mins and maxes.

So in this case,

  • the screen first proposes the screen’s width and height to your view
  • .frame(maxHeight:100) receives the size proposal and creates an invisible frame with the screen’s width and height of 100pt. It changes the size proposal’s height to 100 and passes it down.
  • .padding() receives the size proposal and chooses its size to be the same as the proposed size. It further reduces the size proposal’s width and height by some system-defined padding amount and passes the proposal down.
  • .frame(maxWidth: .infinity) receives the size proposal and adds an invisible frame of the same size as the size proposal. (The orange .background is added to this frame.) It doesn’t change the size proposal and passes it down.
  • .frame(width: 130) receives the size proposal and ignores the proposed width. It creates an invisible frame with width 130pt and same height as the size proposal. The size proposal’s width is now changed to 130pt.
  • Finally, the Rectangle receives the size proposal and chooses its size to be 130pt wide.

Notably, the frame added by .frame(width: 130) is less wide than the frame added byc.frame(maxWidth: .infinity), so changing the alignment parameter of the wider frame from .center to .trailing visibly makes a difference.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading