Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
SwiftUI Cookbook

You're reading from   SwiftUI Cookbook A guide for building beautiful and interactive SwiftUI apps

Arrow left icon
Product type Paperback
Published in Dec 2023
Publisher Packt
ISBN-13 9781805121732
Length 798 pages
Edition 3rd Edition
Languages
Tools
Concepts
Arrow right icon
Author (1):
Arrow left icon
Juan C. Catalan Juan C. Catalan
Author Profile Icon Juan C. Catalan
Juan C. Catalan
Arrow right icon
View More author details
Toc

Table of Contents (20) Chapters Close

Preface 1. Using the Basic SwiftUI Views and Controls 2. Displaying Scrollable Content with Lists and Scroll Views FREE CHAPTER 3. Exploring Advanced Components 4. Viewing while Building with SwiftUI Preview in Xcode 15 5. Creating New Components and Grouping Views with Container Views 6. Presenting Views Modally 7. Navigation Containers 8. Drawing with SwiftUI 9. Animating with SwiftUI 10. Driving SwiftUI with Data 11. Driving SwiftUI with Combine 12. SwiftUI Concurrency with async await 13. Handling Authentication and Firebase with SwiftUI 14. Persistence in SwiftUI with Core Data and SwiftData 15. Data Visualization with Swift Charts 16. Creating Multiplatform Apps with SwiftUI 17. SwiftUI Tips and Tricks 18. Other Books You May Enjoy
19. Index

Using images

Apps need to be appealing to users and need to engage them to interact with the app. To that purpose, a well-crafted and beautiful user interface with simple and intuitive interactions is very desirable.

Images play an important part in an app’s user interface as they add color and simplicity and they convey messages in a graphical way. It is fundamental to master how to use images in your apps.

In this recipe, we will learn how to add an image to a view, use an already existing UIImage, put an image in a frame, and use modifiers to present beautiful images. The images in this section were obtained from https://unsplash.com/, so special thanks to jf-brou, Kieran White, and Camilo Fierro.

Getting ready

Let’s start by creating a new SwiftUI project called UsingImages.

How to do it…

Let’s add some images to our SwiftUI project and introduce the modifiers used to style them. The steps are given here:

  1. Replace the content of the body variable with an empty VStack.
        var body: some View {
            VStack {
            }
        }
    
  2. Download the project images from the GitHub link at https://github.com/PacktPublishing/SwiftUI-Cookbook-3rd-Edition/tree/main/Resources/Chapter01/recipe3/.
  3. Drag and drop the downloaded images for this recipe into the project’s Assets.xcassets (or Assets) folder, as shown in the following screenshot:

Figure 1.6: Assets.xcassets folder in Xcode

  1. Add an Image view to VStack:
    Image("dogs1")
    
  2. Observe the result in the canvas preview.
  3. In iOS 17, the ImageResource and ColorResource structs were introduced, backward compatible to iOS 11 for UIKit and iOS 13 for SwiftUI. Xcode 15 automatically generates instances of ImageResource and ColorResource for images and colors in asset catalogs. For example, the three images in our asset catalog, shown in Figure 1.6, generate the following code:
    // MARK: - Image Symbols -
    @available(iOS 11.0, macOS 10.7, tvOS 11.0, *)
    extension ImageResource {
        /// The "dog-and-nature" asset catalog image resource.
        static let dogAndNature = ImageResource(name: "dog-and-nature", bundle: resourceBundle)
        /// The "dog2" asset catalog image resource.
        static let dog2 = ImageResource(name: "dog2", bundle: resourceBundle)
        /// The "dogs1" asset catalog image resource.
        static let dogs1 = ImageResource(name: "dogs1", bundle: resourceBundle)
    }
    #if canImport(SwiftUI)
    @available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
    extension SwiftUI.Image {
        /// Initialize an 'Image' with an image resource.
        init(_ resource: ImageResource) {
            self.init(resource.name, bundle: resource.bundle)
        }
    }
    #endif
    
  4. This is auto-generated code, compiled along with our own code. Thanks to the new initializer for Image, which takes an ImageResource instead of Image("dogs1"), we can write Image(.dogs1). The advantage of this approach is the compile-time checking of the correct image name, which eliminates runtime errors from typos.
  5. Add a .resizable() modifier to the image and allow SwiftUI to adjust the image such that it fits the screen space available:
    Image(.dogs1)
        .resizable()
    
  6. The .resizable() modifier causes the full image to fit on the screen, but the proportions are distorted. That can be fixed by adding the .aspectRatio(contentMode: .fit) modifier:
    Image(.dogs1)
        .resizable()
        .aspectRatio(contentMode: .fit)
    
  7. Add the dog-and-nature image to VStack:
    Image(.dogAndNature)
        .resizable()
        .aspectRatio(contentMode: .fit)
        .frame(width:300, height:200)
        .clipShape(Circle())
        .overlay(Circle().stroke(.blue, lineWidth: 6))
        .shadow(radius: 10)
    
  8. We can also use a UIImage instance to initialize an Image view. This is useful if the UIImage was generated with legacy code or programmatically. In our example, we use the UIImage convenience initializer, which takes an ImageResource instance. For example, to create a UIImage from the dogs2 image in our asset catalog, we would use: UIImage(resource: .dogs2).
  9. Use the UIImage and display it within the VStack. The resulting code should look like this:
    struct ContentView: View {
        var body: some View {
            VStack{
                Image("dogs1")
                .resizable()
                .aspectRatio(contentMode: .fit)
                Image("dog-and-nature")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width:300, height:200)
                    .clipShape(Circle())
                    .overlay(Circle().stroke(Color.blue,
                     lineWidth: 6))
                    .shadow(radius: 10)
                Image(uiImage: UIImage(resource: .dog2))
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 200, height: 200)
            }
        }
    }
    
  10. The completed application should then look like this:

Figure 1.7: UsingImages preview

How it works…

Adding the Image view to SwiftUI displays the image in its original proportions. The image might be too small or too big for the device’s display. For example, without any modifiers, the dog-and-nature image fills up the full iPhone 14 Pro Max screen:

Figure 1.8: The dog-and-nature image without the resizable modifier

To allow an image to shrink or enlarge to fit the device screen size, add the .resizable() modifier to the image. Adding the .resizable() modifier causes the image to fit within its view, but it may be distorted due to changes in proportion:

Figure 1.9: Image with resizable modifier

To address the issue, add the .aspectRatio(contentMode: .fit) modifier to the image:

Figure 1.10: Image with AspectRatio set

To specify the width and height of an image, add the .frame(width, height) modifier to the view and set the width and height: .frame(width: 200, height: 200).

Images can be clipped to specific shapes. The .clipShape(Circle()) modifier changes the image shape to a circle:

Figure 1.11: Image with the clipShape(Circle()) modifier

The .overlay(Circle().stroke(Color.blue, lineWidth: 6)) and .shadow(radius: 10) modifiers were used to draw a blue line around the image circle and add a shadow to the circle:

Figure 1.12: Stroke and shadow applied to image

Important Note

The order in which the modifiers are added matters. Adding the .frame() modifier before the .resizable() or .aspectRatio() modifiers may lead to different results.

Note that if you set the project deployment target to iOS 14, the ImageResource struct works without issues since Apple made the struct available for older versions of iOS. This allows us to use the new APIs in older versions of iOS in case your app needs to support them.

See also

Apple documentation regarding SwiftUI Image: https://developer.apple.com/documentation/swiftui/image.

lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime