SwiftUI在类中使用Core Data进行计算



在我的项目中,我有一个名为"课程"的核心数据实体。它包含以下属性:-

名称(字符串)

三通(字符串)

hole1no (Int16)

hole1index (Int16)

hole1par (Int16)

我使用fetch请求并选择所需的记录,然后在我的视图中用于变量计算和文本字段。

然后我设置了一个"class"视图使用@Published创建ObsevableObject,以使某些数据可以跨多个视图使用。

我的问题是在我的类设置中,我需要使用从核心数据和视图中输入的数据的数据组合来计算多个视图中需要的变量。

下面是我的代码的副本,在ScoreManager类代码中,我得到了错误消息"类ScoreManager没有初始化项">如果我删除对Course数据的任何引用,它就会消失,所以我假设这就是它在错误中引用的内容。

任何建议将不胜感激,这是我的第一个复杂的项目,所以我很可能在我的知识中错过了一些东西。如果可能的话,你可以更新我的代码,这样我就可以看到哪里的变化是帮助我的学习。

提前感谢。

这是从Core data

获取数据的代码
import SwiftUI
import CoreData
struct Score4PickCourse: View {

@Environment(.managedObjectContext) var moc
@FetchRequest(entity: Course.entity(), sortDescriptors:[NSSortDescriptor(keyPath: Course.name, ascending: false)]) var courses: FetchedResults<Course>

@State private var showingAddScreen = false





var body: some View {


List {
ForEach(courses, id: .self) { course in NavigationLink(destination: Score4SelectPlayers(course: course)) {


VStack(alignment: .leading) {
Text(course.name ?? "Unknown Course")

Text(course.tee ?? "Unknown Tee")

}
}

}

}
.navigationBarTitle("Courses")
.navigationBarItems(trailing: Button(action: {
self.showingAddScreen.toggle()
}) {
Image(systemName: "plus")
}
)
.sheet(isPresented: $showingAddScreen) {
CourseAddNew().environment(.managedObjectContext, self.moc)
}


}

}

这是您输入基本信息(球员姓名,障碍等)的代码。

import SwiftUI
import CoreData
struct Score4SelectPlayers: View {

@Environment(.managedObjectContext) var moc
@Environment(.presentationMode) var presentationMode



@ObservedObject var scoreManager = ScoreManager()

@State private var date = Date()

let course: Course

var body: some View {



Form {

Section {

Text("Course Selected - (course.name ?? "No Course Selected")")

Text("Course Hole No - (course.hole1no)")

Text("Tee Category Selected - (course.tee ?? "No Tee Selected")")

DatePicker("Date of Round", selection: $date, displayedComponents: .date)
.foregroundColor(Color.blue)
.font(.system(size: 17, weight: .bold, design: .rounded))

TextField("Player 1 Name", text: $scoreManager.player1)

Picker("Player 1 Handicap", selection: $scoreManager.p1handicap) {
ForEach(Array(stride(from: 0, to: 55, by: 1)), id: .self) { index in Text("(index)")
}
}       .frame(width: 300, height: 20, alignment: .center)
.foregroundColor(Color.blue)
.font(.system(size: 17, weight: .bold, design: .rounded))
}
}

NavigationLink(destination: Score4Hole1(scoreManager: scoreManager, course: course)) {
Text("Go To Hole 1")

}

}

}

struct Score4SelectPlayers_Previews: PreviewProvider {
static let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)

static var previews: some View {
let course = Course(context: moc)
course.name = "Great Barr"
course.tee = "White Tee"
course.hole1no = 1
course.hole1par = 5
course.hole1index = 10

return NavigationView {
CourseDetailView(course: course)
}
}
}

这是类代码,我需要能够包括数据从核心数据在变量计算

import SwiftUI
import CoreData
class ScoreManager : ObservableObject {

let course: Course

@Published var player1 = ""
@Published var p1handicap = 0

var p1h1shots: Int16 {

let p1h1hand = Int16(p1handicap)
let index = Int16(course.hole1index)
let p1h1shot = p1h1hand - index

if p1h1shot < 0 {
return 0
}
if p1h1shot >= 0 && p1h1shot < 18 {
return 1
}
if p1h1shot >= 18 && p1h1shot < 36 {
return 2
}
if p1h1shot >= 36 && p1h1shot < 54 {
return 3
}
return 0
}


}

我不能测试代码没有最小可重现的例子,但这些变化可以工作。我不知道你会在哪里使用它

1:CoreData对象是ObservableObjects,所以在Score4SelectPlayers中将course更改为@ObservedObject var course: Course

2:在ScoreManager中,将p1h1shots更改为func

func p1h1shots(hole1index: Int16) -> Int16 {
let p1h1hand = Int16(p1handicap)
let p1h1shot = p1h1hand - hole1index

if p1h1shot < 0 {
return 0
}
if p1h1shot >= 0 && p1h1shot < 18 {
return 1
}
if p1h1shot >= 18 && p1h1shot < 36 {
return 2
}
if p1h1shot >= 36 && p1h1shot < 54 {
return 3
}
return 0
}
然后你可以在任何ViewscoreManager.p1h1shots(hole1index: course.hole1index)中使用它

3:你总是可以把它放在你的模型

extension Course{
func p1h1shots(p1handicap: Int16) -> Int16 {
let index = Int16(hole1index)
let p1h1shot = p1handicap - index

if p1h1shot < 0 {
return 0
}
if p1h1shot >= 0 && p1h1shot < 18 {
return 1
}
if p1h1shot >= 18 && p1h1shot < 36 {
return 2
}
if p1h1shot >= 36 && p1h1shot < 54 {
return 3
}
return 0
}
}
然后在你的View 中使用course.p1h1shots(p1handicap: Int16)

最新更新