更改 CoreData 记录,SwiftUI
Making Changes in CoreData record, SwiftUI
我正在使用 SwiftUI 学习核心数据。我想制作一个应用程序,让我可以 post 我喜欢的电影,进行评论并添加评级。
我已经可以在我的应用程序中添加新电影,删除它,查看电影详情。现在我想在 CoreData 中编辑我的记录。我发现这很难,因为我不知道如何将默认值从编辑的电影中放置到我的表单中。
我的代码:
struct EditMovieVIew: View {
let movie: Movie
@Environment(\.presentationMode) var presentationMode
@Environment(\.managedObjectContext) var moc
@State private var title = ""
@State private var director = ""
@State private var review = ""
@State private var genre = "Fantasy"
@State private var rating = 3
@State private var productionYear = Date()
let genres = ["Sci-Fi","Fantasy", "Comedy", "Horror", "Thriller", "Criminal", "Kids", "Romance", "Drama"]
var body: some View {
NavigationView {
Form {
Section {
TextField("Name of movie", text: $title)
TextField("Director's name", text: $director)
}
Section {
DatePicker(selection: $productionYear, in: ...Date(), displayedComponents: .date) {
Text("Date of production")
}
}
Section {
Picker(selection: $genre, label: Text("Genre")) {
ForEach(genres, id: \.self) {
Text([=10=]).tag([=10=])
}
}
}.navigationBarTitle("Select your cheese")
Section {
RatingView(rating: $rating)
TextField("Write a review", text: $review)
}
Section {
Button("Save") {
let newMovie = Movie(context: self.moc)
newMovie.title = self.title
newMovie.director = self.director
newMovie.rating = Int16(self.rating)
newMovie.review = self.review
newMovie.genre = self.genre
newMovie.productionYear = Int16(Calendar.current.component(.year, from: self.productionYear))
try? self.moc.save()
self.presentationMode.wrappedValue.dismiss()
}
}
}
.navigationBarTitle("Add Movie")
}
}
}
struct EditMovieVIew_Previews: PreviewProvider {
static let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
static var previews: some View {
let movie = Movie(context: moc)
movie.title = "Test Movie"
movie.director = "Test director"
movie.genre = "Fantasy"
movie.rating = 4
movie.review = "Good movie"
movie.productionYear = 2019
return NavigationView {
EditMovieVIew(movie: movie)
}
}
}
我也在努力
@Binding var movie: Movie
但我的想法没有一个奏效。
问题出在哪里?
当我想为我的 TextFields 和 Pickers 赋值时,我无法使用我的
text: $movie.title. //OR text: movie.title //OR text: self.movie.title
接下来我要做的是为我的@State 值分配默认值。我写过:@State private var title = self.movie.title
但是 Xcode 说我不能在这里使用 self
和 movie
。
所以我的问题是 - 如何为我的 TextFields 设置默认起始值,以便我能够编辑我的电影并在我的 CoreData 中更新它?
PS。我还有另一个问题。我想让 DatePicker 只用于选择年份。现在我有完整的选择器,然后我只使用用户选择的年份,但我认为只选择一年会更好
I want TextFields to have default value got from original movie
您应该在自定义 init
函数中执行此操作。因为它们是 @State
包裹的,所以您需要跳过一个小环才能正确设置它们。
@State private var title: String // don't set up any initial value here
init(movie: Movie) {
self.movie = movie
self._title = State(initialValue: movie.title ?? "")
// etc.
}
注意 _title
,这意味着您正在初始化包装器而不是包装的值。
对于问题 2,如果您只关心年份,请考虑存储 DateComponents
而不是 Date
,并且只需设置一个自定义选择器而不是 DatePicker
。填充可追溯到 1850 年(或任何时候)的年份数组非常简单。或者有一个年份文本字段。有很多方法可以做到这一点。
我正在使用 SwiftUI 学习核心数据。我想制作一个应用程序,让我可以 post 我喜欢的电影,进行评论并添加评级。
我已经可以在我的应用程序中添加新电影,删除它,查看电影详情。现在我想在 CoreData 中编辑我的记录。我发现这很难,因为我不知道如何将默认值从编辑的电影中放置到我的表单中。
我的代码:
struct EditMovieVIew: View {
let movie: Movie
@Environment(\.presentationMode) var presentationMode
@Environment(\.managedObjectContext) var moc
@State private var title = ""
@State private var director = ""
@State private var review = ""
@State private var genre = "Fantasy"
@State private var rating = 3
@State private var productionYear = Date()
let genres = ["Sci-Fi","Fantasy", "Comedy", "Horror", "Thriller", "Criminal", "Kids", "Romance", "Drama"]
var body: some View {
NavigationView {
Form {
Section {
TextField("Name of movie", text: $title)
TextField("Director's name", text: $director)
}
Section {
DatePicker(selection: $productionYear, in: ...Date(), displayedComponents: .date) {
Text("Date of production")
}
}
Section {
Picker(selection: $genre, label: Text("Genre")) {
ForEach(genres, id: \.self) {
Text([=10=]).tag([=10=])
}
}
}.navigationBarTitle("Select your cheese")
Section {
RatingView(rating: $rating)
TextField("Write a review", text: $review)
}
Section {
Button("Save") {
let newMovie = Movie(context: self.moc)
newMovie.title = self.title
newMovie.director = self.director
newMovie.rating = Int16(self.rating)
newMovie.review = self.review
newMovie.genre = self.genre
newMovie.productionYear = Int16(Calendar.current.component(.year, from: self.productionYear))
try? self.moc.save()
self.presentationMode.wrappedValue.dismiss()
}
}
}
.navigationBarTitle("Add Movie")
}
}
}
struct EditMovieVIew_Previews: PreviewProvider {
static let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
static var previews: some View {
let movie = Movie(context: moc)
movie.title = "Test Movie"
movie.director = "Test director"
movie.genre = "Fantasy"
movie.rating = 4
movie.review = "Good movie"
movie.productionYear = 2019
return NavigationView {
EditMovieVIew(movie: movie)
}
}
}
我也在努力
@Binding var movie: Movie
但我的想法没有一个奏效。
问题出在哪里? 当我想为我的 TextFields 和 Pickers 赋值时,我无法使用我的
text: $movie.title. //OR text: movie.title //OR text: self.movie.title
接下来我要做的是为我的@State 值分配默认值。我写过:@State private var title = self.movie.title
但是 Xcode 说我不能在这里使用 self
和 movie
。
所以我的问题是 - 如何为我的 TextFields 设置默认起始值,以便我能够编辑我的电影并在我的 CoreData 中更新它?
PS。我还有另一个问题。我想让 DatePicker 只用于选择年份。现在我有完整的选择器,然后我只使用用户选择的年份,但我认为只选择一年会更好
I want TextFields to have default value got from original movie
您应该在自定义 init
函数中执行此操作。因为它们是 @State
包裹的,所以您需要跳过一个小环才能正确设置它们。
@State private var title: String // don't set up any initial value here
init(movie: Movie) {
self.movie = movie
self._title = State(initialValue: movie.title ?? "")
// etc.
}
注意 _title
,这意味着您正在初始化包装器而不是包装的值。
对于问题 2,如果您只关心年份,请考虑存储 DateComponents
而不是 Date
,并且只需设置一个自定义选择器而不是 DatePicker
。填充可追溯到 1850 年(或任何时候)的年份数组非常简单。或者有一个年份文本字段。有很多方法可以做到这一点。