How to select and render images in your iOS app using SwiftUI?

In this tutorial, you'll learn to select and render images in your iOS application with a few lines of swift code.

Share:

Feb 25, 2023 590 Words

Read Time: 3 Minutes

A screenshot of iOS application using PhotosPicker using SwiftUI

Introduction

In SwiftUI, the PhotosPicker1 view can be used to select images and videos from the ‘Photos’ application.

Before we dive into the implementation, go through a sample snippet:

Code Snippet Image on using PhotosPicker in SwiftUI XCode

Alternative, get code here

I will explain the parts of this snippet and you can use this to get your job done.

What is PhotosPicker?

PhotosPicker is a view which can be imported from PhotosUI package.

This can be used with SwiftUI.

How does PhotosPicker work?

PhotosPicker returns a PhotosPickerItem2, which can be loaded into a SwiftUI Image object.

There are several ways to programmatically pick images using PhotosPicker. In this example, we shall focus on a straightforward implementation.

We shall give this view:

  1. A label
  2. A variable to hold the PhotosPickerItem object
  3. A filter to help us choose the file type using supported PHPickerFilter

This is how we will place the picker into your app screen using SwiftUI,

PhotosPicker("Random Label", selection: $photos_picker_item, matching: .images)

Let’s try to understand how each of these work,

  1. label’ is a random text string for us to identify the photos picker instance.

  2. selection’ parameter will hold a binding to another variable

    πŸ’‘ A binding means that we are modifying an existing variable.

    We can create a original variable called photos_picker_item to hold the values of Images picked.

    import PhotosUI
    import SwiftUI
    
    // ...
    
    @State var photos_picker_item: PhotosPickerItem?
    @State var image: Image?
    
    // ...
    
    PhotosPicker("Select Image from Photos App", selection: $photos_picker_item, matching: .images)
    .onChange(of: photos_picker_item) { photos_picker_item in
        Task {
            if let data = try? await photos_picker_item?.loadTransferable(type: Data.self) {
                if let uiImage = UIImage(data: data) {
                    image = Image(uiImage: uiImage)
                }
            }
        }
    }
    
    //...
    

    Whatever image is selected using PhotosPicker, will available in photos_picker_item

  3. matching’ is essentially a filter to control what type of files we want the user to select from the photos app.

    This value will be of type PHPickerFilter3 and can specify images, videos, livePhotos, screenshots, timelapseVideos and many more.

Now that we’ve a way to pick files from the Photos app, we need to focus on actually rendering and using the selected file in our app.

We now have a PhotosPickerItem variable photos_picker_item containing the selected file.

Let’s try to convert this into a SwiftUI Image.

import PhotosUI
import SwiftUI

// ...

@State var photos_picker_item: PhotosPickerItem?
@State var image: Image?

//...

PhotosPicker("Select Image from Photos App", selection: $photos_picker_item, matching: .images)
.onChange(of: photos_picker_item) { photos_picker_item in
    Task {
        if let data = try? await photos_picker_item?.loadTransferable(type: Data.self) {
            if let uiImage = UIImage(data: data) {
                image = Image(uiImage: uiImage)
            }
        }
    }
}

//...

How to use PhotosPicker?

We can use the onChange modifier, which fires an action when photos_picker_item is loaded.

The image can be built using the loadTransferable method. This is an asynchronous method.

πŸ’‘ We wrap this inside a Task4 β€” where it concurrently loads the data into an Image in SwiftUI

Now, let’s finally render the Image in SwiftUI,

Code Snippet

import PhotosUI
import SwiftUI

struct ContentView: View {
    
    @State var photos_picker_item: PhotosPickerItem?
    @State var image: Image?

    var body: some View {
        VStack {
            PhotosPicker("Select Image from Photos App", selection: $photos_picker_item, matching: .images)
            .onChange(of: photos_picker_item) { photos_picker_item in
                Task {
                    if let data = try? await photos_picker_item?.loadTransferable(type: Data.self) {
                        if let uiImage = UIImage(data: data) {
                            image = Image(uiImage: uiImage)
                        }
                    }
                }
            }
            image?.resizable().aspectRatio(contentMode: .fit)
        }
    }
}

Demonstration

Here’s how it runs on the XCode5 iOS simulator:

Demo of the PhotosPicker in SwiftUI

πŸ‘‹ – @TnvMadhav

References

Find more posts from following topics

accurate-requests
api-development
api-testing
api-testing-tools
array
automated-testing
bad-habits
base64-decoder
base64-encoder
binding
blog
blogging
bulma-css
bulma.io
button-swiftui
chatgpt
clipboard
code
code-block
code-snippet
comparison
compile
configuring-debugger-for-django-in-vs-code
configuring-launch.json-for-python-debugger
copy
copy-to-clipboard
copy-to-clipboard-neovim
css
current-date
current-time
current-timestamp
debugger-setup-in-visual-studio-code
debugging-django-app-in-visual-studio-code
debugging-python-code-in-visual-studio-code
debugging-python-programs-with-visual-studio-code
debugging-python-with-virtual-environment-in-vs-code
developer-productivity
developers
development-workflow
dom
dynamic-sitemap-in-nextjs
engineering-dashboard
flowcharts
git
git-diff
github
global-keyboard-shorcut
global-shortcut
go
go-hugo
go-programming
go-to-line
golang
golang-development
good-habits
gorilla-websocket
gpt
gpt-3.5
gpt-4
gpt-4-api
guide
gumroad
habits
habits-tracker-notion-template
hamburger-menu
hotkeys
html
hugo
ide
image
image-sharing
image-tool-for-ios
imagerenderer
include-timestamp
integrated-development-environment
ios
ios-16
ios16
javascript
keyboard-shortcut
linux
macos
map
markdown
markdown-code
mental-programming
menu
menubarextra
mermaid-syntax
mistake-tracker-notion
mobile-view
modifier
navbar
navigationlink
navigationstack
neovim
next.js
nextjs
nextjs-markdown
nextjs-sitemap
nextjs-sitemaps
nice-shot
nice-shot-pro
notion
notion-api
notion-api-python
notion-budget
notion-budget-template
notion-budget-tracker
notion-bug-report-tracker
notion-dashboard
notion-expense-manager
notion-habits
notion-habits-dashboard
notion-habits-template
notion-habits-tracker
notion-habits-tracker-template
notion-issue-tracker
notion-mistake-tracker
notion-product
notion-product-dashboard
notion-product-roadmap
notion-product-roadmap-dashboard
notion-tasks
notion-tasks-dashboard
notion-tasks-template
notion-tasks-tracker
notion-template
notionworkspaces
openai
osx
personal-ifttt-framework
photospicker
photospickeritem
phpickerfilter
postman-capabilities
postman-request
pre-request-script
product-roadmap-notion-template
product-roadmap-template
productivity
programming
python
python-api
python-debugger-tutorial-for-vs-code
python-debugging-mode-in-vs-code
python-notion-api
real-time-communication
rehype
remark
request-data
running-debugger-in-visual-studio-code
running-django-app-in-debugging-mode
running-program-in-debugging-mode-in-vs-code
running-python-code-in-debugging-mode
screenshot-app-for-ios
screenshot-app-ios
screenshot-ios
screenshot-tool-for-ios
set-current-timestamp
setting-up-debugger-in-vs-code-for-python
share-extension
sharelink
sharepreview
sharesheet
simple-websocket-server
sitemap
slice
slider
step-by-step-guide
stocks-profits-tracker
stocks-profits-tracker-template
stocks-tracker
struct
sustained-vigilance
swift
swiftui
swiftui-button
swiftui-button-action
swiftui-button-style
table-of-contents
tasks-tracker-notion-template
textfield-swiftui
timeliness
timestamp-integration
transferable
triggers-and-actions
tutorial
us-stocks
usa-stocks
useful-ios-features
using-breakpoints-in-python-debugger
using-virtual-environment-with-python-debugger
vanilla-javascript
variable
vim
visual-mode
visual-studio-code
vs-code
vscode
vscode-go-to-line
web-sockets-in-go
websocket-client
websocket-programming
websocket-server
xcode