質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
Realm

RealmとはSQLiteやCore Dataに代わるモバイルデータベースです。iOSとAndroidの両方でサポートされています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

解決済

Swiftui ObservedResultsについて

asedsa
asedsa

総合スコア3

Realm

RealmとはSQLiteやCore Dataに代わるモバイルデータベースです。iOSとAndroidの両方でサポートされています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

1回答

0評価

0クリップ

283閲覧

投稿2022/06/13 13:43

先日ここで質問させていただいたのですが、
ObservedResultsについてお伺いしたです。
また、
ObservedResultsを使いつつ、ボタンを押し削除する方法を教えていただきたいです。

・質問
具体的にはObservedResultsを使用する際に、
freezeを使用しなくてもデータを削除できると考えているのですが、
どのような書き方になるかを教えていただきたいです。

ObservedResultsを使いViewにデータ(User)を表示させているのですが、
追加することはできても削除することはできません。

コメントアウトしていますが、freezeを使えば削除可能です。(Realmからも)

また、
freezeを使わなくても下記をViewに記載すると削除可能です。(Realmからも)
※望むやり方とは違いますが...

.onDelete(perform: $users.remove)

・やりたいこと
削除を押した時、注意文言が出てきてYesの場合は削除という動作を行いたいです。
※ObservedResultsを使用しつつ、freezeを使わない方法です。

・下記コード
User.swift

import Foundation import RealmSwift class User: Object, ObjectKeyIdentifiable { @Persisted(primaryKey: true) var id: Int = 0 @Persisted var userName: String = "" @Persisted var create_date = Date() override static func primaryKey() -> String? { return "id" } } extension User { private static var config = Realm.Configuration(schemaVersion: 1) private static var realm = try! Realm(configuration: config) static func findAll() -> Results<User> { // realm.objects(self).freeze() realm.objects(self) } static func add(_ user: User) { try! realm.write { realm.add(user, update: .all) } } static func delete(_ user: User) { let actualUser = realm.object(ofType: User.self, forPrimaryKey: user.id)! try! realm.write { realm.delete(actualUser) } } }

UserViewModel.swift

import Foundation import Combine import RealmSwift class UserViewModel: ObservableObject { @Published private(set) var users: [User] = Array(User.findAll()) @Published var userTextField = "" @Published var deleteUser: User? @Published var isDeleteAllTapped = false private var addUserTask: AnyCancellable? private var deleteUserTask: AnyCancellable? init() { addUserTask = self.$userTextField .sink() { username in guard !username.isEmpty else { return } let user = User() user.id = (try! Realm().objects(User.self).max(ofProperty: "id") ?? 0) + 1 user.userName = username User.add(user) // self.users.append(user.freeze()) self.users.append(user) } deleteUserTask = self.$deleteUser .sink() { user in guard let user = user else { return } if let index = self.users.firstIndex(of: user) { do{ self.users.remove(at: index) User.delete(user) }catch { print("Error \(error)") } } } } }

UserView.swift

import SwiftUI import RealmSwift struct UserView: View { @ObservedObject var viewModel = UserViewModel() @ObservedResults(User.self, sortDescriptor: SortDescriptor(keyPath: "create_date", ascending: false)) var users @State private var isUserTextFieldPresented = false @State private var isDeleteAlertPresented = false @State private var isDeleteAllAlertPresented = false @State private var userTextField = "" @State private var deleteUser: User? var body: some View { NavigationView { VStack { if (isUserTextFieldPresented) { TextField("メモを入力してください", text: $userTextField) .textFieldStyle(DefaultTextFieldStyle()) .keyboardType(.asciiCapable) } List { ForEach(users) { user in HStack { UserRowView(user: user) Spacer() Text("削除").onTapGesture { self.deleteUser = user isDeleteAlertPresented.toggle() } .padding() .foregroundColor(.white) .background(Color.red) } .alert(isPresented: $isDeleteAlertPresented) { Alert(title: Text("警告"), message: Text("メモを削除します。\nよろしいですか?"), primaryButton: .cancel(Text("いいえ")), secondaryButton: .destructive(Text("はい")) { viewModel.deleteUser = self.deleteUser } ) } } } } .navigationTitle("メモの一覧") .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button("追加") { if (isUserTextFieldPresented) { viewModel.userTextField = userTextField userTextField = "" } isUserTextFieldPresented.toggle() }.disabled(isUserTextFieldPresented && userTextField.isEmpty) } } } } } // MARK: UserRowView struct UserRowView: View { var user: User var body: some View { VStack(alignment: .leading) { Text(formatDate(user.create_date)) .font(.caption) .fontWeight(.bold) Text(user.userName) .font(.body) } } func formatDate(_ date : Date) -> String { let formatter = DateFormatter() formatter.dateStyle = .long formatter.timeStyle = .medium formatter.locale = Locale(identifier: "ja_JP") return formatter.string(from: date) } }

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Realm

RealmとはSQLiteやCore Dataに代わるモバイルデータベースです。iOSとAndroidの両方でサポートされています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています