0

What exactly is going on in this SwiftUI code I wonder. I want to align the blue view to the leading edge of the safe area in the landscape mode. The below code works but if I remove -0.5 points adjustment in the calculation of blueOffset below, it simply doesn't works. The Blue View simply fills the whole safe area on the leading edge. I wonder what magic -0.5 does?

  @ViewBuilder
    var secondBody:some View {
        Color.green.opacity(0.3)
            .ignoresSafeArea()
            .onGeometryChange(for: CGRect.self) { proxy in
                proxy.frame(in: .global)
            } action: { newValue in
                viewSize = newValue.size
            }
            .background {
                Color.blue
                    .ignoresSafeArea()
                    .aspectRatio(verticalSizeClass == .regular ? 9.0/16.0 : 16.0/9.0, contentMode: .fit)
                    .onGeometryChange(for: CGRect.self) { proxy in
                        proxy.frame(in: .global)
                    } action: { newValue in
                        blueViewSize = newValue.size
//This line, why it works????
                        blueOffset = 
verticalSizeClass == .regular ? 0 :
 (viewSize.width - blueViewSize.width)/2 - 0.5
                        print("Blue offset \(blueOffset)")
                    }
                    .offset(x: -blueOffset)
            }
            .persistentSystemOverlays(.hidden)
    }
7
  • If you want the blue color to not extend beyond the leading side of the safe area, why did you put .ignoresSafeArea() on Color.blue? Commented Mar 8 at 21:22
  • Are you just looking for .ignoresSafeArea(edges: [.vertical, .trailing]) perhaps? Commented Mar 8 at 21:24
  • Can I ask why you're insisting on using geometry proxies when I gave you a complete solution that doesn't require any in your other question? What is the goal? Commented Mar 9 at 1:01
  • @AndreiG. I just want to understand how things work in SwiftUI, it’s not about your solution. Commented Mar 9 at 8:43
  • 1
    @DeepakSharma As a side tip, you don't need two .ignoresSafeArea() modifiers. You can simply have one , if you move it at the end, after .persistentSystemOverlay(.hidden). This way, it will apply to everything above. Commented Mar 9 at 17:13

1 Answer 1

3

For views that like to expand, like Color, they will fill the entire unsafe area as long as they intersect/touch the unsafe area. The -0.5 is basically preventing the blue view from touching the safe area. The actual minimum value you need to subtract is pixelLength - the length of one pixel in points.

That said, if you just want the blue view to respect the leading edge of the safe area, you should just do:

Color.blue
    .ignoresSafeArea(edges: [.vertical, .trailing])

The default value for edges: is .all, so the leading edge is also ignored. Since you don't want to ignore it, you should pass all the other edges, except .leading.

Sign up to request clarification or add additional context in comments.

2 Comments

I didn't know about pixelLength, useful tip!
I wonder if this behaviour of intersecting with safeArea documented anywhere.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.