Sponsor Link
環境&対象
- macOS Big Sur 11.1
- Xcode 12.3
本シリーズ内容
SwiftUI を使って、イメージ処理するアプリを作ります。
以下の理解が進むことがゴールです。
- SwiftUI を使ったアプリ開発
- NSImage を使った画像処理全般
- Photos 拡張編集機能 と SwiftUI app の組み合わせ方
- イメージ処理アプリも TDD で進めることが可能かどうか
- その他 macOS app 開発 Tips
この記事で作る範囲
最初に、画像の上にメガネを重ねて表示することができました。
その後、メガネをドラッグすることで 位置変更できるようにし、追加で、サイズ変更もできるようにしてきました。
今回は、別の画像の上にメガネを重ねることができるようにします。
一言で言うと、別画像のファイルをドロップすることで、画像を入れ替える機能をつけます。
- 画像ファイルをドロップされたら、その写真を表示する
写真をドロップできるようにする
やること
写真ファイルをドロップすると、その画像を表示できるようにします。
ドロップされる要素への対応は、SwiftUI では onDrop で行うことができます。
テスト
テストが難しいです。
実装機能はシンプルなのですが、外部からファイルをドロップする方法がわかりません・・・・・
Finder で新規ウィンドウを開くことまではできるようになったのですが、特定のフォルダまで移動できないので、ドロップできるファイルまで辿り着けません。
# 方法がわかったら この記事をアップデートします。
なので、今回はテストコードは無しです。
手動でテストすることとします。
テスト項目は、以下を想定します。
「画像ファイル(JPG)をドロップしたら、置き換わる」
「画像ファイル(PNG)をドロップしたら、置き換わる」
「画像でないファイルをドロップしたら、無視される」
アプリ実装
以前の記事でも説明しています。
[SwiftUI] SwiftUIのビュー上へのドロップの実装
UITest を作るのは難しいですが、アプリの実装自体は簡単です。
//
// ContentView.swift
//
// Created by : Tomoaki Yagishita on 2021/01/19
// © 2021 SmallDeskSoftware
//
import SwiftUI
import UniformTypeIdentifiers
struct MainView: View {
@State private var image:NSImage = NSImage(named: "initialPhoto")!
@State private var isTargeted = false
var body: some View {
ZStack {
Image(nsImage: image).resizable().scaledToFit().frame(width: 500, height: 500)
.accessibility(identifier: "mainImage")
// (1)
.onDrop(of: [UTType.fileURL], isTargeted: $isTargeted) { (providers) -> Bool in
guard let provider = providers.first else { return false } // handle first item only
// (2)
provider.loadItem(forTypeIdentifier: kUTTypeURL as String, options: nil) { (url, error) in
// (3)
DispatchQueue.main.async {
if let url = url as? Data {
// (4)
let imageURL = NSURL(absoluteURLWithDataRepresentation: url, relativeTo: nil) as URL
if let localImage = NSImage(contentsOf: imageURL) {
// (5)
image = localImage
}
} else if let error = error {
print(error)
}
}
}
return true
}
GlassImage()
}
.padding()
}
}
- .onDrop modifier でドロップを受け取ります
- NSItemProvider の loadItem を使って、ドロップされた情報を受け取ります
- UI 更新が必要となるため、main キューで操作します
- ファイルの URL が渡されるので、そこから NSImage を作ります
- NSImage を作ることができたら、表示イメージにセットします
この記事でできたこと
- イメージのファイルをドロップすることで、画像を置き換える
現在のアプリ
以下のような動作です。
次回
次回以降は 現在の機能を Photos の拡張機能としても使えるようにアプリを変更していきます。
説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。
Sponsor Link