SwiftUI 使用 Core Data 在 Class 中进行计算
SwiftUI Using Core Data for a calculation in a Class
在我的项目中,我有一个名为“Course”的核心数据实体,它包含以下属性:-
姓名(字符串)
tee(字符串)
hole1no (Int16)
hole1index (Int16)
hole1par (Int16)
我使用提取请求和 select 所需的记录,然后在我的视图中用于变量计算和文本字段。
然后我设置了一个“class”视图,使用@Published 创建 ObsevableObject,使某些数据能够跨多个视图使用。
我遇到的问题是在我的 class 设置中,我需要结合使用来自核心数据的数据和在视图中输入的数据来计算多个视图中需要的变量。
下面是我的代码的副本,在 ScoreManager class 代码中我收到了错误消息
"Class ScoreManager 没有初始化器" 如果我删除对课程数据的任何引用,它就会消失,所以我认为这就是它在错误中所指的内容。
任何建议将不胜感激,这是我的第一个复杂项目,所以我可能会遗漏一些知识。如果可能的话,你能不能更新我的代码,这样我就可以看到哪些更改有助于我的学习。
提前致谢。
这是从核心数据中获取数据的代码
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)
}
}
}
这是 class 代码,我需要能够在变量计算中包含来自 Core Data 的数据
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
}
}
我无法在没有 Minimal Reproducible Example 的情况下测试代码,但这些更改可能会起作用。我不知道你会在哪里使用它
第一:
CoreData 对象是 ObservableObjects
,因此在 Score4SelectPlayers
中将 course
更改为 @ObservedObject var course: Course
第二名:
在您的 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
}
然后你可以在任何 View
和 scoreManager.p1h1shots(hole1index: course.hole1index)
中使用它
第三:你总是可以把它放在你的模型中
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)
在我的项目中,我有一个名为“Course”的核心数据实体,它包含以下属性:-
姓名(字符串)
tee(字符串)
hole1no (Int16)
hole1index (Int16)
hole1par (Int16)
我使用提取请求和 select 所需的记录,然后在我的视图中用于变量计算和文本字段。
然后我设置了一个“class”视图,使用@Published 创建 ObsevableObject,使某些数据能够跨多个视图使用。
我遇到的问题是在我的 class 设置中,我需要结合使用来自核心数据的数据和在视图中输入的数据来计算多个视图中需要的变量。
下面是我的代码的副本,在 ScoreManager class 代码中我收到了错误消息 "Class ScoreManager 没有初始化器" 如果我删除对课程数据的任何引用,它就会消失,所以我认为这就是它在错误中所指的内容。
任何建议将不胜感激,这是我的第一个复杂项目,所以我可能会遗漏一些知识。如果可能的话,你能不能更新我的代码,这样我就可以看到哪些更改有助于我的学习。
提前致谢。
这是从核心数据中获取数据的代码
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)
}
}
}
这是 class 代码,我需要能够在变量计算中包含来自 Core Data 的数据
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
}
}
我无法在没有 Minimal Reproducible Example 的情况下测试代码,但这些更改可能会起作用。我不知道你会在哪里使用它
第一:
CoreData 对象是 ObservableObjects
,因此在 Score4SelectPlayers
中将 course
更改为 @ObservedObject var course: Course
第二名:
在您的 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
}
然后你可以在任何 View
和 scoreManager.p1h1shots(hole1index: course.hole1index)
第三:你总是可以把它放在你的模型中
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)