我使用Relam在本地存储数据,工作正常,但当我尝试添加带有导航链接的新记录时,它也会返回重复记录。另一个问题是,当我单击记录时,我希望更改导航,但由于它有重复的记录,第一个记录不起作用,但第二个记录起作用。

这是模型。

import SwiftUI
import RealmSwift

struct Task: Identifiable {
    var id: String
    var title: String
    var completed: Bool = false
    var completedAt: Date = Date()

    init(taskObject: TaskObject) {
            self.id = taskObject.id.stringValue
            self.title = taskObject.title
            self.completed = taskObject.completed
            self.completedAt = taskObject.completedAt
        }
}

这是持久模型。。。

import Foundation
import RealmSwift

class TaskObject: Object {
    @Persisted(primaryKey: true) var id: ObjectId
    @Persisted var title: String
    @Persisted var completed: Bool = false
    @Persisted var completedAt: Date = Date()
}

这是视图模型。。

/

/ 2
final class TaskViewModel: ObservableObject {
    // 3
    @Published var tasks: [Task] = []
    // 4
    private var token: NotificationToken?

    init() {
        setupObserver()
    }

    deinit {
        token?.invalidate()
    }
    // 5
    private func setupObserver() {
        do {
            let realm = try Realm()
            let results = realm.objects(TaskObject.self)

            token = results.observe({ [weak self] changes in
                // 6
                self?.tasks = results.map(Task.init)
                    .sorted(by: { $0.completedAt > $1.completedAt })
                    .sorted(by: { !$0.completed && $1.completed })
            })
        } catch let error {
            print(error.localizedDescription)
        }
    }
    // 7
    func addTask(title: String) {
        let taskObject = TaskObject(value: [
            "title": title,
            "completed": false
        ])
        do {
            let realm = try Realm()
            try realm.write {
                realm.add(taskObject)
            }
        } catch let error {
            print(error.localizedDescription)
        }
    }
    // 8
    func markComplete(id: String, completed: Bool) {
        do {
            let realm = try Realm()
            let objectId = try ObjectId(string: id)
            let task = realm.object(ofType: TaskObject.self, forPrimaryKey: objectId)
            try realm.write {
                task?.completed = completed
                task?.completedAt = Date()
            }
        } catch let error {
            print(error.localizedDescription)
        }
    }

    func remove(id: String) {
        do {
            let realm = try Realm()
            let objectId = try ObjectId(string: id)
            if let task = realm.object(ofType: TaskObject.self, forPrimaryKey: objectId) {
                try realm.write {
                    realm.delete(task)
                }
            }
        } catch let error {
            print(error.localizedDescription)
        }
    }

    func updateTitle(id: String, newTitle: String) {
        do {
            let realm = try Realm()
            let objectId = try ObjectId(string: id)
            let task = realm.object(ofType: TaskObject.self, forPrimaryKey: objectId)
            try realm.write {
                task?.title = newTitle
            }
        } catch let error {
            print(error.localizedDescription)
        }
    }
}

这是主视图。。

@main
struct RelamDemoSwiftUIApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView().environmentObject(TaskViewModel())

        }
    }
}

这是内容视图的代码。。

import SwiftUI

struct ContentView: View {
    var body: some View {
            NavigationView {
                VStack {
                    AddTaskView()
                    TaskListView()
                }
                .navigationTitle("Todo")
                .navigationBarTitleDisplayMode(.automatic)
            }
        }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

以下是添加任务视图的代码。。

import SwiftUI

struct AddTaskView: View {
    @State private var taskTitle: String = ""
    @EnvironmentObject private var viewModel: TaskViewModel

    var body: some View {
        HStack(spacing: 12) {
            TextField("Enter New Task..", text: $taskTitle)
            Button(action: handleSubmit) {
                Image(systemName: "plus")
            }
        }
        .padding(20)
    }

    private func handleSubmit() {
        viewModel.addTask(title: taskTitle)
        taskTitle = ""
    }
}

这是任务列表视图。。

struct TaskListView: View {
    @EnvironmentObject private var viewModel: TaskViewModel
    var body: some View {

        ScrollView {
            
            LazyVStack (alignment: .leading) {
                ForEach(viewModel.tasks, id: \.id) { task in
                    TaskRowView(task: task)
                    Divider().padding(.leading, 20)
                    NavigationLink (destination: TaskView(task: task)) {
                        TaskRowView(task: task)

                }.animation(.default)
                }
            }
        }
    }
}

这是任务代码。。

struct TaskView: View {
    // 1
    @EnvironmentObject private var viewModel: TaskViewModel
    // 2
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
    @State private var taskTitle: String = ""
    // 3
    let task: Task

    var body: some View {
        VStack(alignment: .leading, spacing: 24) {
            // 4
            VStack(alignment: .leading, spacing: 4) {
                Text("Title")
                    .foregroundColor(Color.gray)
                TextField("Enter title..", text: $taskTitle)
                    .font(.largeTitle)
                Divider()
            }
            // 5
            Button(action: deleteAction) {
                HStack {
                    Image(systemName: "trash.fill")
                    Text("Delete")
                }
                .foregroundColor(Color.red)
            }
            Spacer()
        }
        .navigationBarTitle("Edit Todo", displayMode: .inline)
        .padding(24)
        .onAppear(perform: {
            taskTitle = task.title
        })
        // 6
        .onDisappear(perform: updateTask)
    }

    private func updateTask() {
        viewModel.updateTitle(id: task.id, newTitle: taskTitle)
    }

    private func deleteAction() {
        viewModel.remove(id: task.id)
        presentationMode.wrappedValue.dismiss()
    }
}

这是截图enter image description here

swift UI使用Relam返回重复记录的更多相关文章

  1. ios – Realm:无法使用类型'(Object.Type)’的参数列表调用’对象’

    所以我在Realm中有一个非常简单的Book模型而我正在尝试在帮助程序类中检索所有书籍:这一行:抛出标题中的错误.我疯了还是这不是Realm文档告诉我们要做的?解决方法realm.objects()不会返回[Book]但会返回结果?.所以你必须改变userBookLibrary的类型:

  2. ios – Swift 2.0中的动态可选属性

    我已经看过这篇文章OptionaldynamicpropertiesinSwift,但我不想在NSObject中包装该类.这只是关于Realm数据库我没有nil属性,但我认为这是一个很好的方式来建模我的数据库.在可以在https://realm.io/docs/swift/latest/中找到的Realm文档中,它表示支持选项.这是我的码这是我的错误我知道这是与上面的帖子相同的代码和错误,但我很好

  3. ios – 在后台线程中写入Realm后,主线程看不到更新的数据

    >清除数据库.>进行API调用以获取新数据.>将从API检索到的数据写入后台线程中的数据库中.>从主线程上的数据库中读取数据并渲染UI.在步骤4中,数据应该是最新数据,但我们没有看到任何数据.解决方法具有runloops的线程上的Realm实例,例如主线程,updatetothelatestversionofthedataintheRealmfile,因为通知被发布到其线程的runloop.在后台

  4. ios – RxSwift:返回一个带有错误的新observable

    我有一个函数返回BoolObservable,具体取决于它是否正常.解决方法返回包含单个元素的可观察序列.相反,你应该使用这样的东西:Create方法从指定的subscribe方法实现创建一个可观察的序列.在你的情况下:Anonymousdisposable是在您想要中断的情况下调用的操作.假设您离开视图控制器或应用程序需要完成该服务,您不再需要再调用此请求.它非常适合视频上传或更大的内容.您可以

  5. ios – 领域:如何获取数据库的当前大小

    是否有RealmAPI方法使用RealmSwift作为数据存储来获取我的RealmSwift应用程序的当前数据库大小?

  6. ios – 如何绑定Realm对象的更改?

    在我的项目中,我试图通过MVVM工作,所以在.h文件中的VM中在.m文件中GPCity是一个RLMObject子类如何通过ReactiveCocoa绑定此?

  7. ios – Realm在更新多个对象时变慢

    在我的应用中,用户可以在集合视图中选择多个联系人.当他选择属性“isSelected”时,我将设置为true,并且collectionview刷新所选单元格.在这里,我可以识别选择和单元格突出显示之间的小延迟.但是在下一步中,我创建了一个包含所选联系人的组,最后我将属性“isSelected”设置为false.这需要50个对象(5秒)的不可接受的时间量并且需要调整.这是我取消选择所有选定联系人的代码:是否可以立即执行批量更新?解决方法尝试将for循环放在write块中:

  8. 你如何压缩iOS上的Realm DB?

    我想定期在iOS上压缩一个Realm实例来恢复空间.我认为该过程是将数据库复制到临时位置,然后将其复制回来并使用新的default.realm文件.我的问题是Realm()就像一个单例并且回收对象,所以我无法真正关闭它并告诉它打开新的default.realm文件.这里的文档(https://realm.io/docs/objc/latest/api/Classes/RLMRealm.html)建

  9. ios – Realm – 无法使用现有主键值创建对象

    我有一个对象有许多狗的人.应用程序有单独的页面,它只显示狗和其他页面显示人的狗我的模型如下我有人存储在Realm中.人有详细页面,我们取,并显示他的狗.如果狗已经存在,我会更新该狗的最新信息并将其添加到人的狗列表中,否则创建新狗,保存并将其添加到人员列表中.这适用于coredata.在尝试用他的狗更新人时,领域会抛出异常无法使用现有主键值创建对象解决方法这里的问题是,即使你正在创建一个全新的Rea

  10. ios – 领域日期查询

    在Xcode6.3下的我的RealmSwift中,我将如何当前tableView查找对象的数量,如下所示:第一个问题:我怎样才能找到日期条目的对象数量,比如15.06.2014的日期?(即,在RealmSwift-Object的特定日期之上的日期查询–这是如何工作的?将所有Realm-Objects成功填充到tableView中如下所示:第二个问题:我如何填写表格仅查看具有特定日期的RealmSwift-对象.或者换句话说,上面的方法如何只填充tableView具有所需日期范围的对象?

随机推荐

  1. 如何扩展ATmega324PB微控制器的以下宏寄存器?

    我目前正在学习嵌入式,我有以下练习:展开以下宏寄存器:如果有人解决了这个问题,我将不胜感激,以便将来参考

  2. Python将ONNX运行时设置为返回张量而不是numpy数组

    在python中,我正在加载预定义的模型:然后我加载一些数据并运行它:到目前为止,它仍在正常工作,但我希望它默认返回Tensor列表,而不是numpy数组。我对ONNX和PyTorch都是新手,我觉得这是我在这里缺少的基本内容。这将使转换中的一些开销相同。

  3. 在macOS上的终端中使用Shell查找文件中的单词

    我有一个文本文件,其中有一行:我需要找到ID并将其提取到变量中。我想出了一个RexEx模式:但它似乎对我尝试过的任何东西都不起作用:grep、sed——不管怎样。我的一个尝试是:我为这样一个看似愚蠢的问题感到抱歉,但我在互联网上找不到任何东西:我在SO和SE上读了几十个类似的问题,并在谷歌上搜索了几个教程,但仍然无法找到答案。欢迎提供任何指导!

  4. react-chartjs-2甜甜圈图中只有标题未更新

    我正在使用react-chartjs-2在我的网站中实现甜甜圈图。下面是我用来呈现图表的代码。我将甜甜圈图的详细信息从父组件传递到子组件,所有道具都正确传递。当我在beforeDraw函数外部记录props.title时,它会记录正确的值,但当我在beforeDraw函数内部记录props.title时,它将记录标题的前一个值,从而呈现标题的前值。我在这里做错了什么?

  5. 如何在tkinter中使用Python生成器函数?

    生成器函数承诺使某些代码更易于编写。但我并不总是知道如何使用它们。假设我有一个斐波那契生成器函数fib(),我想要一个显示第一个结果的tkinter应用程序。当我点击“下一步”按钮时,它会显示第二个数字,依此类推。我如何构建应用程序来实现这一点?我可能需要在线程中运行生成器。但如何将其连接回GUI?

  6. 如何为每次提交将存储库历史记录拆分为一行?

    我正在尝试获取存储库的历史记录,但结果仅以单行文本的形式返回给我。

  7. 尝试在颤振项目上初始化Firebase时出错

    当尝试在我的颤振项目上初始化firebase时,我收到了这个错误有人知道我能做什么吗?应用程序分级Gradle插件Gradle项目颤振相关性我已经将firebase设置为Google文档已经在另一个模拟器上尝试过,已经尝试过创建一个全新的模拟器,已经在不同的设备上尝试过了,已经尝试了特定版本的firebase,已经尝试添加但没有任何效果,已经在youtube上看到了关于它的每一个视频,该应用程序在android和iOS两个平台上都抛出了这个错误

  8. 在unix中基于当前日期添加新列

    我试图在unix中基于时间戳列在最后一个单元格中添加一个状态列。我不确定如何继续。

  9. 麦克斯·蒙特利。我一直得到UncaughtReferenceError:当我在终端中写入node-v时,节点未定义

    如果这是您应该知道的,请确认:我已将所有shell更改为默认为zsh。当我在终端中写入node-v时,我一直收到“UncaughtReferenceError:nodeisnotdefined”。但它显示节点已安装。我是个新手,在这方面经验不足。

  10. 如何在前端单击按钮时调用后端中的函数?

    那么如何在后端添加一个新的端点,点击按钮调用这个函数。

返回
顶部