SwiftUIでいこう! - 写真を読み出し、保存 2
SenderView()を実装していきます。基本的な画面として写真を選ぶ画面(imagePicker)を開くボタンとその写真表示、
写真の名前、コメント、登録ボタンの4つの部分からなります。
新しいファイルとして作リます。必要なプロパティラッパーを書きます。
@Environment(\.managedObjectContext) private var viewContext
@State var image:Data = .init(count:0)
@State var show = false
@State var name = ""
@State var description = ""
Button(),Image()、TextField,TextField、Button()を作っていきます。
配置としてはこんな感じになります。ここで大事になるのが写真を選ぶこと。imagePickerの機能を使います。これも新しいファイルを作リます。
struct ImagePicker: UIViewControllerRepresentable {}
UIKitの機能を使うので、UIViewControllerRepresentableに準拠させます。
これは決まり文句な要素が多いです。変数は今回のものに合わせます。
import UIKit
import SwiftUI
struct ImagePicker: UIViewControllerRepresentable {
var sourceType: UIImagePickerController.SourceType = .photoLibrary
@Binding var show:Bool
@Binding var image:Data
@Environment(\.presentationMode) private var presentationMode
func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
let imagePicker = UIImagePickerController()
imagePicker.allowsEditing = false
imagePicker.sourceType = sourceType
imagePicker.delegate = context.coordinator
return imagePicker
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
}
func makeCoordinator() -> Coordinator {
return Coordinator(self)
}
final class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
var parent: ImagePicker
init(_ parent: ImagePicker) {
self.parent = parent
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
self.parent.show.toggle()
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let image = info[.originalImage]as! UIImage
let data = image.jpegData(compressionQuality: 0.45)
self.parent.image = data!
self.parent.show.toggle()
}
}
}
これでiPhoneの写真ライブラリから選ぶことができるようになります。
そして登録ボタンを押して保存します。
Button(action:{
let send = Saving(context: self.viewContext)
send.userName = name
send.descriptions = description
send.imageD = image
try? self.viewContext.save()
}){
Text("Send")
.fixedSize()
.frame(width:250,height: 30)
.foregroundColor((self.name.count > 0 && self.description.count > 0 && self.image.count > 0) ? Color.red : Color.black)
.background((self.name.count > 0 && self.description.count > 0 && self.image.count > 0) ? Color.blue : Color.black)
.cornerRadius(13)
}
ボタンは変数descriptionに何か入っている場合にボタンが押せるように、場合分けで表示の色を変えています。
SenderView()で保存したものはContentView()でリスト表示されます。
ContentView()で表示された写真を削除する方法も実装します。まず削除するための関数を作ります。
func deleteTasks(offsets: IndexSet) {
for index in offsets {
viewContext.delete(savings[index])
}
try? viewContext.save()
}
ContentView()のList {}を ForEach()を使ったものに変更して、
.onDelete(perform:deleteTasks) ・・・ 先ほど作った関数を入れます
List {}にForEach()を追加したコードです。
List {
ForEach(savings) { save in
VStack(alignment: .leading){
Image(uiImage: UIImage(data:save.imageD ?? self.image)!)
.resizable()
.frame(width:UIScreen.main.bounds.width - 34,height:210)
.cornerRadius(15)
HStack{
Text("\(save.descriptions ?? "")")
Spacer()
Button(action: {
save.favo.toggle()
try? self.viewContext.save()
}){
Image(systemName: save.favo ? "bookmark.fill" : "bookmark")
}
}
Text("\(save.userName ?? "")")
.font(.caption)
.foregroundColor(.secondary)
}
}
.onDelete(perform:deleteTasks)
}
消したい写真の行を横スライドすればそのデータ、表示されたもの(リスト表示されたもの)、保存されたものを消すことができるようになりました。
この記事が気に入ったらサポートをしてみませんか?