0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【SwiftUI】PhotosPickerで選んだ画像をハイライト表示&高画質プレビューする

Posted at

はじめに

SwiftUIで画像ライブラリを表示しつつ、PhotosPickerで選んだ画像をハイライト表示&高画質プレビューするUI実装をまとめています。

実装イメージ

  • サムネイル一覧を表示(複数選択可能)
  • 選択された画像には白いハイライトを表示
  • タップで高画質プレビュー画面に遷移(fullScreenCover

使用環境

  • Swift 6.1
  • Xcode 16.2
  • SwiftUI

コード

import SwiftUI
import PhotosUI

struct ImageGalleryView: View {
    // PhotosPickerで選択された画像のメタ情報
    @State private var selectedItems: [PhotosPickerItem] = []
    // 実際に表示するUIImageの配列
    @State private var images: [UIImage] = []
    // 現在選択中のインデックス
    @State private var selectedIndex: Int? = nil
    // プレビュー画面の表示フラグ
    @State private var isPreviewPresented = false

    var body: some View {
        NavigationView {
            VStack {
                // 写真選択ボタン(最大10枚)
                PhotosPicker(selection: $selectedItems,
                             maxSelectionCount: 10,
                             matching: .images,
                             photoLibrary: .shared()) {
                    Text("画像選択")
                        .padding()
                        .background(Color.blue)
                        .foregroundColor(.white)
                        .cornerRadius(8)
                }

                // 選択された画像の一覧表示(グリッド)
                ScrollView {
                    LazyVGrid(columns: [GridItem(.adaptive(minimum: 100))], spacing: 10) {
                        ForEach(images.indices, id: \.self) { index in
                            Image(uiImage: images[index])
                                .resizable()
                                .scaledToFill()
                                .frame(width: 100, height: 100)
                                .clipped()
                                // 選択状態を白くハイライト表示
                                .overlay(
                                    RoundedRectangle(cornerRadius: 8)
                                        .fill(Color.white.opacity(selectedIndex == index ? 0.4 : 0.0))
                                )
                                // タップでプレビュー表示へ
                                .onTapGesture {
                                    selectedIndex = index
                                    isPreviewPresented = true
                                }
                        }
                    }
                    .padding()
                }
            }
            .navigationTitle("画像ライブラリ")
        }
        // 選択項目が変更されたときに画像データを読み込み
        .onChange(of: selectedItems) {
            Task {
                images = [] // 初期化
                for item in selectedItems {
                    // Dataとして読み込み → UIImageに変換
                    if let data = try? await item.loadTransferable(type: Data.self),
                       let image = UIImage(data: data) {
                        images.append(image)
                    }
                }
            }
        }
        // フルスクリーンでの画像プレビュー
        .fullScreenCover(isPresented: $isPreviewPresented) {
            if let index = selectedIndex, images.indices.contains(index) {
                ZStack {
                    Color.black.ignoresSafeArea()
                    Image(uiImage: images[index])
                        .resizable()
                        .scaledToFit()
                        .padding()
                }
                // タップで閉じる
                .onTapGesture {
                    isPreviewPresented = false
                }
            }
        }
    }
}

まとめ

SwiftUIの PhotosPicker と組み合わせることで、写真選択・非同期ローディング・UI表現をシンプルに実装できます。特に以下の点が良い学びになりました。

  • 状態管理(@State)とイベント駆動の連携方法
  • 非同期で複数画像を処理するシンプルな書き方
  • overlay による視覚表現の柔軟性
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?