1

I'm learning SwiftUI and noticed some weird behaviour regarding RoundedRectangle, which is used to draw dividers. See in the screenshot below, the RoundedRectangle with width = 1 ignores top and bottom safe area, where as if I use Divider() instead, safe area is respected (see screenshot 2). I've attached the code in the end, what could be the problem? Thanks!

RoundedRectangle

Divider

struct ContentView: View {
    var body: some View {
        TabView {
            NavigationView {
                HStack(spacing: 0) {
                    Spacer()
                    RoundedRectangle(cornerRadius: 0)
                        .frame(width: 1)
                        .overlay(.brown)
                    VStack {
                        Spacer()
                            .frame(height: 40)
                        CustomView()
                        Spacer()
                        CurrentView()
                    }
                }
            }
            .navigationBarTitle("test", displayMode: .inline)
            .tabItem {
                Label(NSLocalizedString("Time", comment: "Tab - Time"), systemImage: "clock")
            }
            Text("Settings")
                .tabItem {
                    Label("Settings", systemImage: "gearshape")
                }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct CustomView: View {
    var body: some View {
        VStack {
            RoundedRectangle(cornerRadius: 0)
                .frame(height: 1)
                .overlay(.brown)
            HStack {
                Text("FIRST".makeVertical())
                Text("SECOND".makeVertical())
                Divider()
                Text("THIRD".makeVertical())
            }
            .padding()
            RoundedRectangle(cornerRadius: 0)
                .frame(height: 1)
                .overlay(.brown)
        }
        .fixedSize(horizontal: true, vertical: true)
    }
}

struct CurrentView: View {

    var body: some View {
        VStack {
            Text("CURRENT")
        }
    }
}
extension String {
    func makeVertical() -> String {
        map { String($0) }
            .joined(separator: "\n")
    }
}
Heuristic
  • 5,087
  • 9
  • 54
  • 94

1 Answers1

1

You can try adding this command line

.padding(.vertical, 1)

into RoundedRectangle of HStack.

HStack(spacing: 0) {
    Spacer()
    RoundedRectangle(cornerRadius: 0)
        .frame(width: 1)
        .overlay(.brown)
        .padding(.vertical, 1) // <-- Add here
        
    VStack {
        Spacer()
            .frame(height: 40)
        CustomView()
        Spacer()
        CurrentView()
    }
}

Result: enter image description here

baohoang
  • 616
  • 1
  • 5
  • 13
  • Thanks, it does work! I wonder what's the reason behind this, is it because after adding `padding` the "low level" drawing shape will be wrapped with a higher level SwiftUI component which then respects safe area? – Heuristic Apr 21 '23 at 00:20
  • No @Heuristic The issue you're experiencing is related to how RoundedRectangle and Divider handle safe area insets. Divider takes the safe area insets into account automatically and adjusts its height accordingly, whereas RoundedRectangle does not. This is why in your example, the RoundedRectangle with width 1 ignores the top and bottom safe area. – baohoang Apr 21 '23 at 03:05