ios - SwiftUI View Offset relative to safe area - Stack Overflow

admin2025-04-17  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)
    }

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)
    }
Share edited Mar 8 at 21:17 Deepak Sharma asked Mar 8 at 21:01 Deepak SharmaDeepak Sharma 6,66110 gold badges67 silver badges162 bronze badges 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? – Sweeper Commented Mar 8 at 21:22
  • Are you just looking for .ignoresSafeArea(edges: [.vertical, .trailing]) perhaps? – Sweeper 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? – Andrei G. Commented Mar 9 at 1:01
  • @AndreiG. I just want to understand how things work in SwiftUI, it’s not about your solution. – Deepak Sharma 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. – Andrei G. Commented Mar 9 at 17:13
 |  Show 2 more comments

1 Answer 1

Reset to default 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.

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1744885164a272490.html

最新回复(0)