xcode 在重新启动预览之前,将项目添加到CoreData时,视图不会更新

3df52oht  于 2023-05-01  发布在  其他
关注(0)|答案(1)|浏览(112)

我试图创建一个带有可以添加或删除的圆圈的滚动视图(在SwiftUI中使用CoreData),但当我创建新圆圈时(从另一个视图),圆圈不会出现。重新加载预览后,将显示创建的项目。然而,删除它们本身工作得很好,但它发生在视图中。
我该怎么弥补?
代码如下:

个人资料菜单

import SwiftUI

struct ProfileMenu: View {
    
    @State var circles : [Circle] = []
    @ObservedObject var vm = CircleViewModel()
    
    let colors1 : [Color] = ...
    let colors2 : [Color] = ...
    let colors3 : [Color] = ...
    
    @State var showCircleInfoScreen : Bool = false
    
    var body: some View {
        ZStack {
            ScrollView(.horizontal){
                LazyHStack {
                    ForEach(vm.savedCircles) { circle in
                        createCircle(name: circle ?? "error", isBlue: circle.isBlue)
                        
                    }
                    addCircleButton
                }
            }
            if showCircleInfoScreen {
                CircleView(showCircleInfoScreen: $showCircleInfoScreen)
            }
        }
    }
    
    
    var addCircleButton : some View {
        
        Button {
            withAnimation(.easeIn(duration: 0.1)) {
                showCircleInfoScreen.toggle()
            }
            
        } label: {
            VStack {
                Text("ADD")
                    //some modifiers
                ZStack {
                    Circle()
                    //some modifiers
                    Text("+")
                    //some modifiers
                }
                .padding(10)
            }
        }
    }
    
    func createCircle(name: String, isBlue: Bool) -> some View  {
        Button {
            //
        } label: {
            VStack {
                Text(name)
                    //some modifiers
                Circle()
                    //some modifiers
                    .overlay {
                        ZStack {
                            Circle()
                    //some modifiers
                            Text(...)
                        }
                        .contextMenu {
                            Button {
                                vm.deleteCircleInfo(name: name)
                            } label: {
                                Text("Delete info")
                            }
                            
                        }
                    }
                    .padding(10)
            }
        }
    }
    
    
    
    struct ProfileMenu_Previews: PreviewProvider {
        static var previews: some View {
            ProfileMenu()
        }
    }
}

CircleView

import SwiftUI
import CoreData

class CircleViewModel : ObservableObject {
    
    @Published var savedCircles: [Circle] = []
    
    let container : NSPersistentContainer

    
    init() {
        container = NSPersistentContainer(name: "CircleContainer")
        container.loadPersistentStores { (description, error) in
            if let error = error {
                print("ERROR LOADING CORE DATA: \(error)")
            }
        }
        fetchCircleContainer()
    }
    
    func fetchCircleContainer() {
        let request = NSFetchRequest<Circle>(entityName: "Circle")
        
        do {
            savedCircles = try container.viewContext.fetch(request)
        } catch let error {
            print("Error fetching. \(error)")
        }
        
    }
    
    func saveCircles() {
        do {
            try container.viewContext.save()
            fetchCircleContainer()
        } catch let error {
            print("Error saving Circle entity. \(error)")
        }
    }
    
    func addCircle(name: String, isBlue: Bool) {
        let newCircle = Circle(context: container.viewContext)
        newCircle.name = name
        newCircle.isBlue = isBlue
        saveCircles()
    }
    
    func deleteCircleInfo(name: String) {
        guard let index = savedCircles.firstIndex(where: {$0.name == name}) else { return }
        let entity = savedCircles[index]
        container.viewContext.delete(entity)
        saveCircles()
    }
    
    
}

struct CircleView: View {
    
    @State var textFieldText = ""
    
    @StateObject var vm = CircleViewModel()
    
    @Binding var showCircleInfoScreen : Bool
    
    let colors1 : [Color] = ...
    let colors2 : [Color] = ...
    let colors3 : [Color] = ...
    let colors4 : [Color] = ...
    
    let bgColors : [Color] = ...
    
    @State var selectedColor : String = ""
    @State var isRedColorSelected : Bool = false
    @State var isBlueColorSelected : Bool = false
    @State var selectionReady : Bool = false
    
    @State var circleName : String = ""
    
    var body: some View {
        
        ZStack {
            
            Rectangle()
                    //some modifiers
            VStack(spacing: 30) {
                Text("CIRCLE INFO")
                    //some modifiers
                Text("NAME")
                    //some modifiers
                TextField(("CIRCLE NAME"), text: $circleName)
                    //some modifiers
                
                Text("COLOR")
                    //some modifiers
                HStack (spacing: 40) {
                    
                    redButton
                    blueButton
                    
                    
                }
                Spacer()
                continueButton
                
            }
            Button {
                withAnimation(.easeIn(duration: 0.3)) {
                    showCircleInfoScreen.toggle()
                }
            } label: {
                Image(systemName: "xmark")
                    //some modifiers
            }
            .frame(maxWidth: .infinity,maxHeight: .infinity, alignment: .topLeading)
        }
    }
    
    var redButton : some View {
        Button {
            withAnimation(.spring(...)) {
                isRedColorSelected.toggle()
                isBlueColorSelected = false
            }
        } label: {
            Circle()
                //some modifiers
        }
        .buttonStyle(.plain)
        
        
    }
    
    var blueButton : some View {
        Button {
            withAnimation(.spring(...)) {
                isBlueColorSelected.toggle()
                isRedColorSelected = false
            }
        } label: {
            Circle()
                //some modifiers
        }
        .buttonStyle(.plain)
    }
    
    var continueButton : some View {
        
        Button {
            vm.addCircle(name: circleName, isBlue: isBlueColorSelected)
            withAnimation(.easeIn(duration: 0.3)) {
                showCircleInfoScreen.toggle()
            }
        } label: {
            ZStack {
                RoundedRectangle(cornerRadius: 10)
                    //some modifiers
                RoundedRectangle(cornerRadius: 10)
                    //some modifiers
                Text("Continue")
                    //some modifiers
                
            }
        }
        .disabled(!(isBlueColorSelected || isRedColorSelected))
    }
}

struct CircleView_Previews: PreviewProvider {
    static var previews: some View {
        CircleView(showCircleInfoScreen: .constant(true))
    }
}
ao218c7q

ao218c7q1#

这是因为您使用了视图模型的两个不同示例,所以保存& delete方法只会更新其中一个视图模型。
您需要做的是只创建一个示例,然后将其传递给其他视图。
首先在CircleView中将视图模型更改为ObservedObject

@ObservedObject var viewModel: CircleViewModel

然后将在ProfileMenu中创建的示例传递给CircleView

if showCircleInfoScreen {
    CircleView(viewModel: vm, showCircleInfoScreen: $showCircleInfoScreen)
}

相关问题