Hendersonick
Hendersonick

Reputation: 61

Trying to format an image in the top right corner – SwiftUI

I am attempting to program an iOS app with a settings button in the top right corner. I tried using a Spacer to get the SF Symbol image to stay in the top right but when I use a single spacer it pushes the image beyond the boundaries of the screen. Is it possible for me to add constraints to keep the image in the top right, without it going outside the boundaries of the screen? and if possible, to keep the image in the top right on all iOS devices? I am very new to SwiftUI so any insights and advice are appreciated!

Here is the code I am using:

import SwiftUI

struct ContentView: View {
    var body: some View {
    // view code
    ZStack {
        Image("Background").resizable()
            .aspectRatio(contentMode: .fill).ignoresSafeArea()
        
        VStack{
            
            HStack {
            
            Button(action: {}, label: {
                Image(systemName: "gear").resizable().aspectRatio(contentMode: .fit)
                    .frame(width: 50, height: 50)                })
            }
            .padding()
            
            Spacer()
    
            HStack {
                
                
                Button(action: {}, label: {
                    Image(systemName: "plus")
                        .resizable().aspectRatio(contentMode: .fit).frame(width: 150, height: 150, alignment: .center).padding().border(Color.white, width: 8).cornerRadius(10.0).foregroundColor(.white)
                })
            }
            Spacer()
            
        }
    }
    
    
    
    
}
       
With spacer Without spacer
Settings image overflows out of right side of screen Settings image centered horizontally

Upvotes: 5

Views: 6858

Answers (1)

aheze
aheze

Reputation: 30318

Edit: Because your image is in a ZStack, it will expand and overflow the screen. You should use the background modifier instead.

struct ContentView: View {
    var body: some View {
        VStack{
            HStack {
                Spacer()
                
                Button(action: {}, label: {
                        Image(systemName: "gear").resizable().aspectRatio(contentMode: .fit)
                            .frame(width: 50, height: 50)                })
            }
            .padding()
            
            Spacer()
            
            HStack {
                Button(action: {}, label: {
                    Image(systemName: "plus")
                        .resizable().aspectRatio(contentMode: .fit).frame(width: 150, height: 150, alignment: .center).padding().border(Color.white, width: 8).cornerRadius(10.0).foregroundColor(.white)
                })
            }
            Spacer()
        }
        
        /// here!
        .background(
            Image("Background")
                .resizable()
                .aspectRatio(contentMode: .fill)
                .ignoresSafeArea()
        )
    }
}

Result:

Image of gradient in background, plus icon centered, settings icon at top-right

If you're using a ZStack to layer the background, a view inside there might be expanding beyond the edges. I've tried to reproduce what you want below, but it would be helpful if you posted some more code.

struct ContentView: View {
    var body: some View {
        ZStack {
            LinearGradient(gradient: Gradient(colors: [.blue, .green]), startPoint: .top, endPoint: .bottom)
                .ignoresSafeArea()
            
            Image(systemName: "plus")
                .resizable()
                .foregroundColor(.white)
                .frame(width: 200, height: 200)
            
            VStack{
                HStack {
                    Spacer()
                    
                    Button(action: { }) {
                        Image(systemName: "gear")
                            .resizable()
                            .foregroundColor(.white)
                            .frame(width: 50, height: 50)
                        
                    }
                }
                
                Spacer()
            }
        }
    }
}

Result:

gradient background, plus icon centered, settings icon at top-right

Upvotes: 6

Related Questions