Ios 当用户使用SwiftUI进入新视图时,如何刷新核心数据阵列?
我有三种观点。内容视图、培训视图和培训列表视图。我想列出核心数据中的练习,但也希望在不改变数据的情况下进行一些更改 在ContentView中;我正在尝试使用CoreData获取数据Ios 当用户使用SwiftUI进入新视图时,如何刷新核心数据阵列?,ios,swift,core-data,swiftui,Ios,Swift,Core Data,Swiftui,我有三种观点。内容视图、培训视图和培训列表视图。我想列出核心数据中的练习,但也希望在不改变数据的情况下进行一些更改 在ContentView中;我正在尝试使用CoreData获取数据 struct ContentView: View { // MARK: - PROPERTY @FetchRequest( sortDescriptors: [NSSortDescriptor(keyPath: \Training.timestamp, ascending:
struct ContentView: View {
// MARK: - PROPERTY
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \Training.timestamp, ascending: false)],
animation: .default)
private var trainings: FetchedResults<Training>
@State private var showingAddProgram: Bool = false
// FETCHING DATA
// MARK: - FUNCTION
// MARK: - BODY
var body: some View {
NavigationView {
Group {
VStack {
HStack {
Text("Your Programs")
Spacer()
Button(action: {
self.showingAddProgram.toggle()
}) {
Image(systemName: "plus")
}
.sheet(isPresented: $showingAddProgram) {
AddProgramView()
}
} //: HSTACK
.padding()
List {
ForEach(trainings) { training in
TrainingListView(training: training)
}
} //: LIST
Spacer()
} //: VSTACK
} //: GROUP
.navigationTitle("Good Morning")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: {
print("test")
}) {
Image(systemName: "key")
}
}
} //: TOOLBAR
.onAppear() {
}
} //: NAVIGATION
}
private func showId(training: Training) {
guard let id = training.id else { return }
print(id)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
}
}
另外,我正在添加视频:
我想做的是,当用户点击任何训练练习时,列表都应该刷新。应该是x5,就像一开始一样。我很难理解你的问题,但我想我明白了 我的理解是:
练习
生成一个不同的结构
(类似练习显示
),然后将练习显示
传递到培训视图
扩展名
写入练习
,并在将模型传递到培训视图
之前“复制”模型。为此,您需要实现NSCopying
协议
扩展练习:NSCopying{
func副本(带区域:NSZone?=nil)->任何{
返回练习(……)
}
}
但在执行此操作之前,我想您需要将.xcdatamodeld
文件中的Codegen更改为Manual/None。当您想要手动创建属性时,这是必需的。我不确定如何为CoreDate模型实现NSCopying
,但它确实是可行的
第一种方法比较简单,但有点难看。第二种更通用、更优雅,但也更先进。只要先尝试第一种方法,一旦你感到自信,就转向第二种方法
更新: 下面简要介绍如何实施第一种方法:
struct ExerciseDisplay:可识别、可平衡{
公共let id=UUID()
公共let名称:String
公共变量代表:Int
公众休息时间:Int
}
结构训练视图:视图{
//其他属性和状态等。
让培训:培训
@状态变量练习:[ExerciseDisplay]=[]
初始(培训:培训){
自我训练
}
var body:一些观点{
VStack{
//观点
}
.onAppear(){
让存储:[练习]=训练.练习?.toArray()??[]
self.exerces=stored.map{ExerciseDisplay(名称:$0.name??”,rep:Int($0.rep),rest:Int($0.rest))}
}
}
}
这里的问题到底是什么?你能澄清你的问题吗?@JoakimDanielson我添加了额外的资源。@Hüseyinİyibaş你能不能因为其他利益而将其标记为接受?@emrcftci是的,这是正确的,我接受了。
import SwiftUI
struct TrainingView: View {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
@State var training: Training
@State var exercises: [Exercise]
@State var tempExercises: [Exercise] = [Exercise]()
@State var timeRemaining = 0
@State var timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
@State var isTimerOn = false
var body: some View {
VStack {
HStack {
Text("\(training.name ?? "")")
Spacer()
Button(action: {
presentationMode.wrappedValue.dismiss()
}) {
Text("Finish")
}
}
.padding()
ZStack {
Circle()
.fill(Color.blue)
.frame(width: 250, height: 250)
Circle()
.fill(Color.white)
.frame(width: 240, height: 240)
Text("\(timeRemaining)s")
.font(.system(size: 100))
.fontWeight(.ultraLight)
.onReceive(timer) { _ in
if isTimerOn {
if timeRemaining > 0 {
timeRemaining -= 1
} else {
isTimerOn.toggle()
stopTimer()
removeExercise()
}
}
}
}
Button(action: {
startResting()
}) {
if isTimerOn {
Text("CANCEL")
} else {
Text("GIVE A BREAK")
}
}
Spacer()
ExerciseListView(exercises: $tempExercises)
}
.navigationBarHidden(true)
.onAppear() {
updateBigTimer()
}
}
private func startResting() {
tempExercises = exercises
if let currentExercise: Exercise = tempExercises.first {
timeRemaining = Int(currentExercise.rest)
startTimer()
isTimerOn.toggle()
}
}
private func removeExercise() {
if let currentExercise: Exercise = tempExercises.first {
if Int(currentExercise.rep) == 1 {
let index = tempExercises.firstIndex(of: currentExercise) ?? 0
tempExercises.remove(at: index)
} else if Int(currentExercise.rep) > 1 {
currentExercise.rep -= 1
let index = tempExercises.firstIndex(of: currentExercise) ?? 0
tempExercises.remove(at: index)
tempExercises.insert(currentExercise, at: index)
}
updateBigTimer()
}
}
private func updateBigTimer() {
timeRemaining = Int(tempExercises.first?.rest ?? 0)
}
private func stopTimer() {
timer.upstream.connect().cancel()
}
private func startTimer() {
timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
}
}
struct TrainingView_Previews: PreviewProvider {
static var previews: some View {
TrainingView(training: Training(), exercises: [Exercise]())
}
}
struct TrainingListView: View {
@ObservedObject var training: Training
@Environment(\.managedObjectContext) private var managedObjectContext
var body: some View {
NavigationLink(destination: TrainingView(training: training, exercises: training.exercises?.toArray() ?? [Exercise]())) {
HStack {
Text("\(training.name ?? "")")
Text("\(training.exercises?.count ?? 0) exercises")
}
}
}
}