Image view in SwiftUI

Working with image in SwiftUI is so easy. There are several way we can add image to our project.

Using image from Assets.xcassets

If we put an image in Assets.xcassets, we can use in our app like this:

 Image("imageName")

We can resize and make it fit into available space like this:

            Image("coffee")
                .resizable()
                 .scaledToFit()

We will get output like this:

We can set custom width and weight like this:

        Image("coffee")
                .resizable()
                .scaledToFit()
                .frame(width: 300, height: 300)

.scaledToFit() will help us to maintain aspect ratio.

Instead of fit the image to available space, we can fill the space using   .scaledToFill():

     Image("coffee")
                .resizable()
                .scaledToFill()

It will scale the image and will try to fill the whole space. Output:

SF Symbols

When we create an app in Xcode, we see that an image and a text view already added in the template. That image used from SF Symbols. We can use SF Symbols icons in our app by passing it’s name in Image view like this:

 Image(systemName: "globe")

We can customise SF Symbols same as a Text view like this:

           Image(systemName: "globe")
               .font(.system(size: 200))
               .foregroundColor(.green)

Output:

SF Symbols animations

You can animate SF Symbols like pulse, bounce, scale etc. Here is an quick example:

     Image(systemName: "globe")
               .font(.system(size: 200))
               .foregroundColor(.green)
               .symbolEffect(.pulse)

You can animate an icon when it’s tapped:

import SwiftUI
struct ContentView: View {
    @State var isTapped = false
    var body: some View {
        Image(systemName: "baseball.fill")
            .font(.system(size: 100))
            .symbolEffect(.bounce, value: isTapped)
            .onTapGesture {
                isTapped.toggle()
            }
    }
}
#Preview {
    ContentView()
}

More example:

import SwiftUI
struct ContentView: View {

    @State var isTapped = false
    var body: some View {
        VStack{
            Image(systemName: "globe")
               .font(.system(size: 100))
               .foregroundColor(.green)
               .symbolEffect(.pulse)
            
            // Variable Color
            Image(systemName: "wand.and.rays")
                .font(.system(size: 100))
                .symbolEffect(.variableColor.iterative.reversing)
            
            // Bounce
            Image(systemName: "baseball.fill")
                .font(.system(size: 100))
                .symbolEffect(.bounce, value: isTapped)
                .onTapGesture {
                    isTapped.toggle()
                }
            
            // Speed and Repeat
            Image(systemName: "cloud.drizzle.fill")
                .font(.system(size: 100))
                .symbolEffect(.variableColor.iterative.reversing, options: .speed(10))
 
            
        }
        .padding()
    }
}
#Preview {
    ContentView()
}

Async Image

Using AsyncImage, we can load and show an image from URL:

 AsyncImage(url: URL(string: "https://picsum.photos/536/354"))

We can resize AsyncImage like regular image. Here is the way to resize Async Image:

    AsyncImage( url: URL(string: "https://picsum.photos/536/354"),
                    content: { image in
            image.resizable()
                .aspectRatio(contentMode: .fit)
                .frame(maxWidth: 300, maxHeight: 300)
        },
                    placeholder: {
            ProgressView()
        })

Image with Text

Here is an example of how you can use Image and Text together:

import SwiftUI

struct ContentView: View {
    var body: some View {
        
        ZStack(alignment: .bottom){
            Image("jellyfish")
                .resizable()
                .clipShape(RoundedRectangle(cornerRadius: 10))
                .aspectRatio(contentMode: .fill)
            
            
            VStack(alignment: .leading){
                Text("Image Title")
                    .font(.headline)
                
            }
            .padding()
            .frame(maxWidth: .infinity)
            .background(.ultraThinMaterial)
            .opacity(0.9)
            .clipShape(RoundedRectangle(cornerRadius: 10))
        }
        .frame(width: 200, height: 250)
        .shadow(radius: 10)
    }
}

#Preview {
    ContentView()
}

Output:

More about Image & ImageVIew:

Leave a Reply