-1.6 C
New York
Friday, January 17, 2025

Side Ratios in SwiftUI · objc.io

Side Ratios in SwiftUI · objc.io


One of many modifiers that all the time puzzled me a bit was .aspectRatio. How does it actually work? As soon as I figured it out, it turned out to be less complicated than I assumed.

One place the place we will discover out lots about how SwiftUI works is SwiftUI’s .swiftinterface file. That is situated inside Xcode. Inside your Terminal, go to /Functions/Xcode.app, and carry out the next command:

								discover . -path "*/SwiftUI.framework*swiftinterface"

							

There are just a few variants of the .aspectRatio API, however all of them boil all the way down to a single implementation:

								func aspectRatio(_ aspectRatio: CGFloat?, contentMode: ContentMode) -> some View {
    
}

							

The variant with CGSize simply calls this methodology with measurement.width/measurement.top, and .scaledToFit and .scaledToFill name this methodology with the respective content material modes and an aspectRatio of nil.

After we name aspectRatio with a set side ratio, e.g. .aspectRatio(16/9, contentMode: .match), the side ratio implementation takes the proposed measurement, and proposes a brand new measurement to its youngster. When the content material mode is .match, it suits a rectangle with the specified side ratio contained in the proposed measurement. For instance, if you suggest 100×100, it’s going to suggest 100×56.2 to its youngster. Whenever you select .fill as an alternative, it’s going to suggest 177.8×100 to its youngster as an alternative.

I discovered this conduct by printing the proposed sizes. Extra on that beneath.

Maybe the most typical use of aspectRatio is mixed with a resizable picture, like so:

								Picture("take a look at")
    .resizable()
    .aspectRatio(contentMode: .match)

							

This can draw the picture to suit throughout the proposed measurement. Observe that we don’t specify the precise side ratio: it’s derived from the underlying picture.

After we do not specify a set side ratio however use nil for the parameter, the side ratio modifier appears on the perfect measurement of the underlying view. This implies it merely proposes nil×nil to the underlying view, and makes use of the results of that to find out the side ratio. For instance, when the picture studies its perfect measurement as 100×50, the computed side ratio is 100/50.

The method then continues like earlier than: when the view was proposed 320×480, the picture will likely be sized to 320×160 when the content material mode is about to .match, and 960×480 when the content material mode is about to .fill.

Determining proposed sizes

Proposed sizes aren’t a part of the general public API of SwiftUI. Regardless that you completely want to grasp how this works as a way to write efficient layouts, this is not actually documented. The one official place the place this conduct is described is within the wonderful 2019 WWDC speak Constructing Customized Views with SwiftUI.

Nevertheless, there’s a hack to do that. Contained in the interface file talked about above, I looked for “ProposedSize” and located a protocol named _ArchivableView which permits us to override sizeThatFits:

								struct MySample: _ArchivableView {
    var physique: some View {
        Rectangle()
    }
    
    func sizeThatFits(in proposedSize: _ProposedSize) -> CGSize {
        print(proposedSize.fairly)
        return proposedSize.orDefault
    }
}

							

We are able to now merely assemble a MySample with a side ratio and print the end result. As an alternative of a .body, you may also use .fixedSize() to suggest nil for the width and/or top. Likewise, attempt leaving out the primary parameter and see how .aspectRatio proposes nil to determine the best measurement of its youngster view.

								MySample()
    .aspectRatio(100/50, contentMode: .fill)
    .body(width: 320, top: 480)

							

Sadly the width and top properties on _ProposedSize aren’t seen within the swift interface, so I had to make use of introspection to print these (and likewise add just a few helper strategies like .fairly and .orDefault). The total code is in a gist.

If you wish to be taught extra about how SwiftUI works, learn our ebook Considering in SwiftUI. When your organization is already constructing issues in SwiftUI — or is about to get began — think about reserving a SwiftUI Workshop on your workforce.

author avatar
roosho Senior Engineer (Technical Services)
I am Rakib Raihan RooSho, Jack of all IT Trades. You got it right. Good for nothing. I try a lot of things and fail more than that. That's how I learn. Whenever I succeed, I note that in my cookbook. Eventually, that became my blog. 
rooshohttps://www.roosho.com
I am Rakib Raihan RooSho, Jack of all IT Trades. You got it right. Good for nothing. I try a lot of things and fail more than that. That's how I learn. Whenever I succeed, I note that in my cookbook. Eventually, that became my blog. 

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here


Latest Articles

author avatar
roosho Senior Engineer (Technical Services)
I am Rakib Raihan RooSho, Jack of all IT Trades. You got it right. Good for nothing. I try a lot of things and fail more than that. That's how I learn. Whenever I succeed, I note that in my cookbook. Eventually, that became my blog.