skip to Main Content

I want to make the image to ignore safe areas and reach the top of the phone (past the camera and where time is shown)

This is the code I have right now::

import SwiftUI

struct ArtistView: View {
    
    var artist: Artist
    
    var body: some View {
        ScrollView {
            VStack {
                Image("theWeeknd_banner")
                    .resizable()
                    .ignoresSafeArea(.container, edges: .top)
                    .scaledToFill()
                    .frame(width: .infinity, height: 300)
                    // .offset(y: -59)
            }
        }
    }
}

It’s just under the selfie camera but I want to have it at the top of the phone like shown in the screenshot. Offsetting it by y: -59 brings it to the top on a device like iPhone 15 Pro but its too much for the SE. This is the closest I got to getting the result I want.

enter image description here

I’ve also tried this from another post:

struct ArtistView: View {
    
    var artist: Artist
    
    var body: some View {
        ScrollView {
            ZStack {
                Color.clear
                    .background(
                        Image("theWeeknd_banner")
                            .resizable()
                            .ignoresSafeArea()
                            .scaledToFill()
                            
                    )
            }
        }
    }
}

It’s at the top but goes over the top and cuts off a bit of the image.

enter image description here

If anyone could help with the image filling into a certain a height (so it would have the height it needs to be and zoomed in a bit of the width is too much) it would be nice too.

Hopefully it’s enough info

2

Answers


  1. You can use the .clipped() modifier to clip the image to avoid going over the top if you want to use ignoreSafeArea()

    or if you want to set dynamic offset according to the device, you can use geometryReader() to get the safe area based on the current device (Ex: iPhone 15 Pro, SE )

    GeometryReader { geometry in
        ScrollView {
            ZStack(alignment: .top) {
                Color.clear
                    .background(
                        Image("theWeeknd_banner")
                            .resizable()
                            .ignoresSafeArea(.container, edges: .top)
                            .scaledToFill()
                            .frame(width: .infinity, height: 300)
                            .offset(y: -geometry.safeAreaInsets.top)
                    )
            }
        }
    }
            
    
    Login or Signup to reply.
  2. Assuming you want the image to scroll with the main content, one way would be to put a GeometryReader around the ScrollView, to measure the screen size and the safe area insets.

    • The ScrollView should ignore safe areas at the top and sides.
    • The main content should be given a minimum width equal to the screen width.
    • Apply the safe area insets as padding to the main content.
    • The image can be shown as the background behind the main content.
    • If you want the image to have a minimum height then this can be achieved by applying a minimum height to the actual content.
    • Apply .clipped below the image, if you don’t want it overflowing past the main content.
    var body: some View {
        GeometryReader { proxy in
            ScrollView {
                VStack {
                    Text("Main content")
                        .font(.largeTitle)
                        .foregroundStyle(.white)
                }
                .frame(minWidth: proxy.size.width)
                .padding(.top, proxy.safeAreaInsets.top)
                .padding(.leading, proxy.safeAreaInsets.leading)
                .padding(.trailing, proxy.safeAreaInsets.trailing)
                .frame(minHeight: 200)
                .background {
                    Image(systemName: "tortoise.fill")
                        .resizable()
                        .ignoresSafeArea()
                        .scaledToFill()
                        .foregroundStyle(.gray)
                        .background(.green)
                }
                .clipped()
            }
            .ignoresSafeArea(edges: [.top, .leading, .trailing])
        }
    }
    

    Screenshot

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search