ホーム画面とメモ詳細画面のメモ内容を同期させる

ソースコード:MyColorMemoAppSwiftUI

コード

//

import SwiftUI
import RealmSwift

struct HomeView: View {
    @ObservedResults(MemoDataModel.self) var memoDataList

    var body: some View {
        NavigationStack {
	@@ -12,9 +13,6 @@ struct HomeView: View {
                Spacer()
            }
        }
    }

    /// メモ一覧.
	@@ -23,9 +21,9 @@ struct HomeView: View {
            ForEach(memoDataList, id: \.self) { memo in
                NavigationLink(
                    destination:
                        MemoDetailView(memoData: memo)
                ) {
                    memoCell(memo)
                }
            }
        }
        .listStyle(.plain)
    }
}
// MARK: View Components
extension HomeView {
    /// メモ一覧に表示するセル.
    func memoCell(_ memo: MemoDataModel) -> some View {
        VStack(alignment: .leading) {
            // メモのテキスト
            Text(memo.text)
                .font(.body)
            // メモの作成・編集日時
            Text(formatDate.string(from: memo.recordDate))
                .font(.footnote)
        }
    }
}
extension HomeView {
    // 表示形式を変更した日付
    var formatDate: DateFormatter {
        let formatter = DateFormatter()
        // Apple が推奨する固定フォーマット用ロケール
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.timeZone = TimeZone(identifier: "UTC")
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
        return formatter
    }
}
#Preview {
    HomeView()
}

//

import SwiftUI
import RealmSwift
struct MemoDetailView: View {
    /// 新規作成または編集するメモの情報.
    /// Binding($○○)で値を変更すると、自動的にRealmにも反映される
    @ObservedRealmObject var memoData: MemoDataModel
    /// TextEditorのフォーカス.
    @FocusState var isFocused: Bool

    var body: some View {
        TextEditor(text: $memoData.text)
            .focused($isFocused)
            .toolbar {
                ToolbarItemGroup(placement: .keyboard) {
                    HStack {
                        Spacer()
                        keyboardCloseButton
                    }
                }
            }
            .navigationTitle(dateFormatter.string(from: memoData.recordDate))
            .onDisappear {
                // 新規作成されたメモかどうかを判定
                if memoData.realm == nil {
                    // テキストが空でなければ保存(空のままなら保存しない)
                    if !memoData.text.isEmpty {
                        saveData()
                    }
                } else {
                    // 既存メモの場合は、最終編集日時だけ更新
                    updateDate()
                }
            }
    }
    
    /// キーボードを閉じるボタン.
    var keyboardCloseButton: some View {
        Button(
            action: {
                isFocused = false
            }, label: {
                Text("done")
            }
        )
    }
}

extension MemoDetailView {
    /// Date型の値を年月日に表示を変換する.
    var dateFormatter: DateFormatter {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy年MM月dd日"
        return dateFormatter
    }
    
    /// Realmにメモデータを保存する.
    func saveData() {
        let realm = try! Realm()
        try! realm.write {
            memoData.recordDate = Date()
            realm.add(memoData)
        }
        print(memoData)
    }

    /// メモデータの日付を更新する.
    func updateDate() {
        // Bindingでない場合のRealmオブジェクトの更新
        // 本来Realmオブジェクトは安全性のため編集不可なので、
        // thawで解凍し、解凍したオブジェクトのwrite内で更新する
        let data = memoData.thaw()
        try! data?.realm?.write {
            // 解凍後のデータを使って、recordDateを更新
            data?.recordDate = Date()
        }
    }
}

#Preview {
    @Previewable let memo = MemoDataModel()
    MemoDetailView(memoData: MemoDataModel())
}
  • ユーザー名:
  • 受講プラン:
  • 完了ステータス:未完了
cta_img

受講申し込みはこちらから

まずは受講用アカウントの作成からスタート。
iOSアカデミアの受講に必要な各種情報を記載した、ご案内メールをお届けします。

受講申し込み