Home > Net >  Ignore safe area in scroll view but not its subviews
Ignore safe area in scroll view but not its subviews

Time:09-29

Looking at the following subview, you can see that it extends to the full width of the screen and takes the notch into account, which is great.

struct EventSubtitleView: View {
    
    let model: EventSubtitleViewModel
    
    var body: some View {
        Text(model.subtitle)
            .frame(maxWidth: .infinity, alignment: .leading)
            .font(.subheadline)
            .padding()
            .background(ColorPanel.oceanBlue.color)
            .foregroundColor(ColorPanel.lightCream.color)
    }
}

enter image description here

Using this view as a subview in a larger scene looks great too. But this scene has an issue with text clipping at the bottom.

enter image description here

struct EventDetailView: View {
    
    let model: EventDetailViewModel
    
    var body: some View {
        ZStack(alignment: .top) {
            ColorPanel.lightCream.color
                .ignoresSafeArea()
            VStack(spacing: 0) {
                EventTitleView(title: model.title)
                EventSubtitleView(model: model.subtitleViewModel)
                EventMessageView(message: model.message)
            }
        }
    }
}

So if I introduce a scroll view that fixes the issue.

enter image description here

But now my blue subview no longer extends to the edges of the screen.

struct EventDetailView: View {
    
    let model: EventDetailViewModel
    
    var body: some View {
        ZStack(alignment: .top) {
            ColorPanel.lightCream.color
                .ignoresSafeArea()
            ScrollView {
                VStack(spacing: 0) {
                    EventTitleView(title: model.title)
                    EventSubtitleView(model: model.subtitleViewModel)
                    EventMessageView(message: model.message)
                }
            }
        }
    }
}

How do I get the blue view to extend to the edges of the screen in a scroll view?

CodePudding user response:

I think the blue view is somehow limited by the frame of scrollview. You can overcome it by using a rectangle with the same color with its frames width set to screen size width and height to screen size width divided by some number so you keep the same dimensions across all devices.

let screenSize: CGRect = UIScreen.main.bounds

struct SwiftUIView: View {
var body: some View {
    ScrollView {
        VStack {
            ZStack {
                Rectangle()
                    .fill(Color.blue)
                    .frame(width: screenSize.width, height: screenSize.width / 3, alignment: .top)
                Text("<text on the blue background>")
            }
            Text("<other text below the blue background>")
        }
    }
}

Blue rectangle in a scrollview

Then just add your text and you're good to go

CodePudding user response:

  1. Wrap your scroll view with GeometryReader, so you can access safeAreaInsets values.
  2. Inside GeometryReader apply ignoresSafeArea: if you apply it outside, safeAreaInsets is gonna be zero.
  3. Add padding before background using ignoresSafeArea values
GeometryReader { geometry in
    ScrollView {
        ForEach(0..<10) { i in
            HStack {
                Text("\(i)")
                Spacer()
            }
            .padding(.leading, geometry.safeAreaInsets.leading)
            .padding(.trailing, geometry.safeAreaInsets.trailing)
            .background(i % 2 == 0 ? Color.blue : .clear)
        }
    }
    .ignoresSafeArea(edges: .horizontal)
}

Result:

  • Related