Dayem Saeed
Dayem Saeed

Reputation: 380

How can I give a background Image to my View in SwiftUI

I'm new to SwiftUI and iOS and I'm having trouble getting my VStack to stack items properly. Mainly, it looks like the image on the top left is too big. Here's a screenshot of the size of the image in my layout:

layout image

This is what it should look like:

what layout should look like

This is the SwiftUI code:

    @State private var email: String = ""
    @State private var password: String = ""
    @State private var isEditing = false
    var body: some View {
        return VStack(content: {
            
            Image("UIBubble")
                .resizable()
                .frame(width: 217, height: 184, alignment: .leading)
                .position(x: 108, y: 92);

            Text("PET SUPPORT").font(Font.custom("Permanent Marker", size: 36))
                .foregroundColor(Color.petSupportText)
                .padding()
                .frame(width: .infinity, height: 0, alignment: .center);
            
            Text("EMAIL").font(Font.custom("Permanent Marker", size: 18))
                .padding(.top, 20)
                .padding(.horizontal, 0)
                .frame(width: .infinity, height: 0, alignment: .leading);
            
            TextField("Email", text: $email) {
                isEditing in self.isEditing = isEditing
            }
            .autocapitalization(.none)
            .disableAutocorrection(true)
            .padding(.horizontal, 30)
            .padding(.top, 20);
            
            Divider()
                .padding(.horizontal, 30)
                .foregroundColor(.black);
            
            Text("PASSWORD").font(Font.custom("Permanent Marker", size: 18)).padding(.top, 50).padding(.horizontal, 0).frame(width: .infinity, height: 20, alignment: .leading);
            
            TextField("Password", text: $password) {
                isEditing in self.isEditing = isEditing
            }
            .autocapitalization(.none)
            .disableAutocorrection(true)
            .padding(.horizontal, 30)
            .padding(.top, 20)
            
            Divider().padding(.horizontal, 30).foregroundColor(.black);
            
        })
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .ignoresSafeArea()
    }

Image giving me trouble:

bubble image

The image itself is 217x184.

Upvotes: 4

Views: 3727

Answers (2)

Daniel Pustotin
Daniel Pustotin

Reputation: 535

Seems like you can just use background(alignment:content:) modifier

So, add this background modifiers to your view:

VStack {
    ...
}
.background(alignment: .topLeading) {
    Image("UIBubble")
}
.background(alignment: .bottomTrailing) {
    Image("UIBubble2"),
}

In my opinion this solution is the most swifty

Upvotes: 3

swiftPunk
swiftPunk

Reputation: 1

You should use ZStack for this work or send the Image to background like in code:

Also I made some code for you to make you free to use that file Image and you get same and much more better result with system shape. you can change the Color, shape, size, number of bubble and every thing . .


enter image description here


with usage of contrast: make the Color like your Color

enter image description here

import SwiftUI

struct ContentView: View {
    
    @State private var email: String = ""
    @State private var password: String = ""
    @State private var showPassword = false
    
    var body: some View {
        
        return VStack(content: {
            
            Spacer()
                .frame(height: 100)
            
            Text("PET SUPPORT")
                .font(Font.custom("Permanent Marker", size: 36))
                .padding()
            
            Group {
                
                HStack {
                    
                    Text("EMAIL")
                        .font(Font.custom("Permanent Marker", size: 18))
                        .padding(.top, 20)
                    
                    Spacer()
                    
                }
                
                TextField("Email", text: $email)
                    .autocapitalization(.none)
                    .disableAutocorrection(true)
                    .keyboardType(.emailAddress)      // <<: Here:  A type optimized for multiple email address entry (shows space @ . prominently).
                    .padding(.top, 20)
                
                
                Divider()
                    .foregroundColor(.black)
                
            }
            
            
            Group {
                
                HStack {
                    
                    Text("PASSWORD")
                        .font(Font.custom("Permanent Marker", size: 18))
                        .padding(.top, 50)
                    
                    Spacer()
                    
                }
                
                ZStack {
                    
                    if showPassword {
                        TextField("Password", text: $password)
                    }
                    else {
                        SecureField("Password", text: $password)
                    }
                    
                }
                .frame(height: 20)
                .overlay(Image(systemName: showPassword ? "eye.slash" : "eye").onTapGesture { showPassword.toggle() }, alignment: .trailing)
                .autocapitalization(.none)
                .disableAutocorrection(true)
                .padding(.top, 20)
                
                Divider()
                    .foregroundColor(.black)
                
            }
            
            
            
            Group {
                
                Button("Sign Up") {}
                    .padding()
                
                Button("Login") {}
                    .padding()
                
            }
            
            Spacer()
            
        })
        .padding(.horizontal, 30)
        .background(bubble, alignment: .topLeading)
        .background(bubble.rotationEffect(Angle(degrees: 180)), alignment: .bottomTrailing)
        .ignoresSafeArea()
        .statusBar(hidden: true)
        
    }

    var bubble: some View {   // <<: you can put this part out and use update code for this part

        Image("UIBubble")
            .resizable()
            .scaledToFit()
            .frame(width: 217, height: 184, alignment: .leading)

    }
    
}

Update: you can replace that file Image with high quality system shape like this code!

var bubble: some View {
   
    ZStack {
        
        Circle()
            .fill(Color(UIColor.systemTeal).opacity(0.2))   // <<: Here: opacity = 0.2
            .frame(width: 300, height: 300, alignment: .center)
            .offset(x: -100, y: -180)
        
        
        Circle()
            .fill(Color(UIColor.systemTeal).opacity(0.2))   // <<: Here: opacity = 0.2
            .frame(width: 300, height: 300, alignment: .center)
            .offset(x: -180, y: -100)
        
    }
    .contrast(3.0)           // <<: Here: This make your Color POP out!

}

Update 2: with this down code your Circle/bubble came to live and they move with smooth animation.

@State private var startAnimation: Bool = false

var bubble: some View {
    
    ZStack {
        
        Circle()
            .fill(Color(UIColor.systemTeal).opacity(0.2))   // <<: Here: opacity = 0.2
            .frame(width: 300, height: 300, alignment: .center)
            .offset(x: startAnimation ? -110 : -100, y: startAnimation ? -180 : -150)
        
        
        Circle()
            .fill(Color(UIColor.systemTeal).opacity(0.2))   // <<: Here: opacity = 0.2
            .frame(width: 300, height: 300, alignment: .center)
            .offset(x: startAnimation ? -180 : -150, y: startAnimation ? -90 : -100)
        
    }
    .contrast(3.0)                   // <<: Here: This make your Color POP out!
    .onAppear() { startAnimation = true }
    .animation(Animation.easeInOut(duration: 3.0).repeatForever(autoreverses: true))
    
}

Upvotes: 3

Related Questions