Skip to main content

How to let users select pictures using PhotosPicker

About 2 minSwiftSwiftUIArticle(s)bloghackingwithswift.comcrashcourseswiftswiftuixcodeappstore

How to let users select pictures using PhotosPicker 관련

SwiftUI by Example

Back to Home

How to let users select pictures using PhotosPicker | SwiftUI by Example

How to let users select pictures using PhotosPicker

Updated for Xcode 15

New in iOS 16

SwiftUI's PhotosPicker brings up the system-standard photo import user interface, allowing users to select one or more images or videos to bring in to your app.

To use it to bring in an image, you need to import the PhotosUI module, then create some storage for a PhotosPickerItem to save what the user selected, and also an Image property to store the loaded asset. You can then watch for the PhotosPickerItem changing, and load its contents like this:

import PhotosUI
import SwiftUI

struct ContentView: View {
    @State private var avatarItem: PhotosPickerItem?
    @State private var avatarImage: Image?

    var body: some View {
        VStack {
            PhotosPicker("Select avatar", selection: $avatarItem, matching: .images)

            avatarImage?
                .resizable()
                .scaledToFit()
                .frame(width: 300, height: 300)
        }
        .onChange(of: avatarItem) {
            Task {
                if let loaded = try? await avatarItem?.loadTransferable(type: Image.self) {
                    avatarImage = loaded
                } else {
                    print("Failed")
                }
            }
        }
    }
}

Download this as an Xcode projectopen in new window

If you want more control over the data that is selected, adjust the matching parameter based on what you're looking for:

  • Use matching: .screenshots if you only want screenshots.
  • Use matching: .any(of: [.panoramas, .screenshots]) if you want either of those types.
  • Use matching: .not(.videos) if you want any media that isn't a video.
  • Use matching: .any(of: [.images, .not(.screenshots)])) if you want all kinds of images except screenshots.

If you want to let the user select multiple images, you should use an array of PhotosPickerItem objects then load them individually using a similar process:

import PhotosUI
import SwiftUI

struct ContentView: View {
    @State private var selectedItems = [PhotosPickerItem]()
    @State private var selectedImages = [Image]()

    var body: some View {
        NavigationStack {
            ScrollView {
                LazyVStack {
                    ForEach(0..<selectedImages.count, id: \.self) { i in
                        selectedImages[i]
                            .resizable()
                            .scaledToFit()
                            .frame(width: 300, height: 300)
                    }
                }
            }
            .toolbar {
                PhotosPicker("Select images", selection: $selectedItems, matching: .images)
            }
            .onChange(of: selectedItems) {
                Task {
                    selectedImages.removeAll()

                    for item in selectedItems {
                        if let image = try? await item.loadTransferable(type: Image.self) {
                            selectedImages.append(image)
                        }
                    }
                }
            }
        }
    }
}

Download this as an Xcode projectopen in new window

Similar solutions…
How to let users import videos using PhotosPicker | SwiftUI by Example

How to let users import videos using PhotosPicker
Article(s) > How to let users select text

How to let users select text
Article(s) > How to let users select a color with ColorPicker

How to let users select a color with ColorPicker
How to let the user select multiple dates | SwiftUI by Example

How to let the user select multiple dates
How to let users pick options from a menu | SwiftUI by Example

How to let users pick options from a menu

이찬희 (MarkiiimarK)
Never Stop Learning.