Ios 核心数据对象仍保存在presentationMode SwiftUI中的Disclose/cancel上

Ios 核心数据对象仍保存在presentationMode SwiftUI中的Disclose/cancel上,ios,swift,core-data,swiftui,Ios,Swift,Core Data,Swiftui,当我试图取消/取消添加对象模式时,它会创建一个空对象,而不仅仅是取消 我尝试过deleteObject、context.rollback()和其他一些随机操作。希望得到帮助,并能回答任何问题 通过在NavigationBarItem中放置Cancel按钮,我意识到这不是一个问题,但我希望能够理解如何创建单独的“Cancel(或Disclose)”按钮 ContentView.swift import SwiftUI import CoreData struct ContentView: Vi

当我试图取消/取消添加对象模式时,它会创建一个空对象,而不仅仅是取消

我尝试过deleteObject、context.rollback()和其他一些随机操作。希望得到帮助,并能回答任何问题

通过在NavigationBarItem中放置Cancel按钮,我意识到这不是一个问题,但我希望能够理解如何创建单独的“Cancel(或Disclose)”按钮

ContentView.swift

import SwiftUI
import CoreData


struct ContentView: View {
    @Environment(\.managedObjectContext) var moc
    @FetchRequest(entity: Game.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Game.gameName, ascending: true)]) var games: FetchedResults<Game>
    @State private var showingAddGame = false


    var body: some View {
        GeometryReader { geometry in
            NavigationView {
                List {
                    ForEach(self.games, id: \.self) { games in
                        NavigationLink(destination: GameGoalsDetail(game: games)) {
                            VStack(alignment: .leading) {
                                Text(games.gameName ?? "Unknown Game")
                                Text(games.gameDescription ?? "Unknown Game Description")
                            }
                        }
                    }
                    .onDelete(perform: self.removeGames)
                    }

                .navigationBarItems(leading:
                    HStack {
                        Button(action: {
                                self.showingAddGame.toggle()
                            }) {
                                Text("Add Game")
                                    .padding(.top, 50)
                                    .foregroundColor(Color.yellow)
                        }.sheet(isPresented: self.$showingAddGame) {
                                AddGameView().environment(\.managedObjectContext, self.moc)
                        }
                        Image("Game Goals App Logo")
                        .resizable()
                        .frame(width: 100, height: 100)
                        .padding(.leading, (geometry.size.width / 2.0) + -160)
                        .padding(.bottom, -50)
                    }, trailing:
                        EditButton()
                            .padding(.top, 50)
                            .foregroundColor(Color.yellow)
                            )
            }
        }
    }

    func removeGames(at offsets: IndexSet) {
        for index in offsets {
            let game = games[index]
            moc.delete(game)
        }
        try? moc.save()
    }
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
        let newGame = Game(context: context)
        newGame.gameName = "Apex Legends"
        newGame.gameDescription = "Maybe this will work"
        return ContentView().environment(\.managedObjectContext, context)
    }
}
import SwiftUI
import CoreData


struct AddGameView: View {

    @Environment(\.managedObjectContext) var moc
    @FetchRequest(entity: Game.entity(), sortDescriptors: []) var games: FetchedResults<Game>
    @Environment(\.presentationMode) var presentationMode

    @State private var gameName = ""
    @State private var gameDescription = ""
    @State private var showingAlert = false

    var body: some View {
        Form {
            Section {
                TextField("Game Name", text: $gameName)
                TextField("Game Description", text: $gameDescription)
            }
            HStack {
                Button("Add Game") {
                    let newGame = Game(context: self.moc)
                    newGame.gameName = self.gameName
                    newGame.gameDescription = self.gameDescription

                    do {
                        try self.moc.save()
                        self.presentationMode.wrappedValue.dismiss()
                    } catch {
                        print("Whoops! \(error.localizedDescription)")
                    }

                }
                Button(action: {
                    self.presentationMode.wrappedValue.dismiss()
                }) {
                    Text("Cancel")
                }
                .padding(10)
                .foregroundColor(Color.white)
                .background(Color.red)
            }
        }
    }
}

struct AddGameView_Previews: PreviewProvider {
    static var previews: some View {
        AddGameView()
    }
}
导入快捷界面
导入CoreData
结构ContentView:View{
@环境(\.managedObjectContext)变量moc
@FetchRequest(实体:Game.entity(),SortDescriptor:[NSSortDescriptor(keyPath:\Game.gameName,升序:true)])var games:FetchedResults
@国家私有变量showingame=false
var body:一些观点{
GeometryReader{中的几何体
导航视图{
名单{
ForEach(self.games,id:\.self){games in
导航链接(目的地:游戏目标详细信息(游戏:游戏)){
VStack(对齐:。前导){
文本(games.gameName??“未知游戏”)
文本(games.gamesdescription??“未知游戏描述”)
}
}
}
.onDelete(执行:self.removeGames)
}
.navigationBarItems(领先:
HStack{
按钮(操作:{
self.showingame.toggle()
}) {
文本(“添加游戏”)
.padding(.top,50)
.foregroundColor(颜色.黄色)
}.表(显示:self.$showingAddGame){
AddGameView().environment(\.managedObjectContext,self.moc)
}
图像(“游戏目标应用程序徽标”)
.可调整大小()
.框架(宽度:100,高度:100)
.padding(.leading,(geometry.size.width/2.0)+-160)
.padding(.bottom,-50)
},尾随:
编辑按钮()
.padding(.top,50)
.foregroundColor(颜色.黄色)
)
}
}
}
func removeGames(偏移量处:IndexSet){
对于偏移量中的索引{
让游戏=游戏[索引]
主运行中心删除(游戏)
}
试试看?moc.save()
}
}
结构内容视图\u预览:PreviewProvider{
静态var预览:一些视图{
让上下文=(UIApplication.shared.delegate为!AppDelegate)。persistentContainer.viewContext
让newGame=Game(上下文:上下文)
newGame.gameName=“顶点传奇”
newGame.gameDescription=“也许这会有用”
返回ContentView().environment(\.managedObjectContext,context)
}
}
AddGameView.swift

import SwiftUI
import CoreData


struct ContentView: View {
    @Environment(\.managedObjectContext) var moc
    @FetchRequest(entity: Game.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Game.gameName, ascending: true)]) var games: FetchedResults<Game>
    @State private var showingAddGame = false


    var body: some View {
        GeometryReader { geometry in
            NavigationView {
                List {
                    ForEach(self.games, id: \.self) { games in
                        NavigationLink(destination: GameGoalsDetail(game: games)) {
                            VStack(alignment: .leading) {
                                Text(games.gameName ?? "Unknown Game")
                                Text(games.gameDescription ?? "Unknown Game Description")
                            }
                        }
                    }
                    .onDelete(perform: self.removeGames)
                    }

                .navigationBarItems(leading:
                    HStack {
                        Button(action: {
                                self.showingAddGame.toggle()
                            }) {
                                Text("Add Game")
                                    .padding(.top, 50)
                                    .foregroundColor(Color.yellow)
                        }.sheet(isPresented: self.$showingAddGame) {
                                AddGameView().environment(\.managedObjectContext, self.moc)
                        }
                        Image("Game Goals App Logo")
                        .resizable()
                        .frame(width: 100, height: 100)
                        .padding(.leading, (geometry.size.width / 2.0) + -160)
                        .padding(.bottom, -50)
                    }, trailing:
                        EditButton()
                            .padding(.top, 50)
                            .foregroundColor(Color.yellow)
                            )
            }
        }
    }

    func removeGames(at offsets: IndexSet) {
        for index in offsets {
            let game = games[index]
            moc.delete(game)
        }
        try? moc.save()
    }
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
        let newGame = Game(context: context)
        newGame.gameName = "Apex Legends"
        newGame.gameDescription = "Maybe this will work"
        return ContentView().environment(\.managedObjectContext, context)
    }
}
import SwiftUI
import CoreData


struct AddGameView: View {

    @Environment(\.managedObjectContext) var moc
    @FetchRequest(entity: Game.entity(), sortDescriptors: []) var games: FetchedResults<Game>
    @Environment(\.presentationMode) var presentationMode

    @State private var gameName = ""
    @State private var gameDescription = ""
    @State private var showingAlert = false

    var body: some View {
        Form {
            Section {
                TextField("Game Name", text: $gameName)
                TextField("Game Description", text: $gameDescription)
            }
            HStack {
                Button("Add Game") {
                    let newGame = Game(context: self.moc)
                    newGame.gameName = self.gameName
                    newGame.gameDescription = self.gameDescription

                    do {
                        try self.moc.save()
                        self.presentationMode.wrappedValue.dismiss()
                    } catch {
                        print("Whoops! \(error.localizedDescription)")
                    }

                }
                Button(action: {
                    self.presentationMode.wrappedValue.dismiss()
                }) {
                    Text("Cancel")
                }
                .padding(10)
                .foregroundColor(Color.white)
                .background(Color.red)
            }
        }
    }
}

struct AddGameView_Previews: PreviewProvider {
    static var previews: some View {
        AddGameView()
    }
}
导入快捷界面
导入CoreData
结构AddGameView:视图{
@环境(\.managedObjectContext)变量moc
@FetchRequest(实体:Game.entity(),sortDescriptors:[])var games:FetchedResults
@环境(\.presentationMode)变量presentationMode
@国家私有var gameName=“”
@国家私有var gameDescription=“”
@国家私有变量showingAlert=false
var body:一些观点{
形式{
部分{
文本字段(“游戏名”,文本:$gameName)
TextField(“游戏描述”,文本:$gameDescription)
}
HStack{
按钮(“添加游戏”){
让newGame=Game(上下文:self.moc)
newGame.gameName=self.gameName
newGame.gameDescription=self.gameDescription
做{
尝试self.moc.save()
self.presentationMode.wrappedValue.discouse()文件
}抓住{
打印(“哎哟!\(错误。本地化描述)”)
}
}
按钮(操作:{
self.presentationMode.wrappedValue.discouse()文件
}) {
文本(“取消”)
}
.填充(10)
.foregroundColor(颜色.白色)
.背景(颜色.红色)
}
}
}
}
结构AddGameView\u预览:PreviewProvider{
静态var预览:一些视图{
AddGameView()
}
}

我已经搜索了所有地方,所以如果有什么我错过了stackoverflow帖子,请链接它,因为我不仅想解决这个问题,而且想了解原因。

您的取消按钮没有创建空对象。问题在于,表单中具有“添加”和“取消”按钮的整行是交互式的,会触发两个按钮的操作

我在这里找到了答案: 要保持当前布局,只需在每个按钮上添加一行即可:

.buttonStyle(BorderlessButtonStyle())
在此之后,只需点击每个按钮即可触发操作。带有按钮的窗体行将不可单击

还有另外两种解决方案。两者都是为了把你的按钮移出形式

解决方案1 将按钮移动到NavigationBarItems,如下所示:

导入快捷键 导入CoreData

struct AddGameView: View {
    
    @Environment(\.managedObjectContext) var moc
    @FetchRequest(entity: Game.entity(), sortDescriptors: []) var games: FetchedResults<Game>
    @Environment(\.presentationMode) var presentationMode
    
    @State private var gameName = ""
    @State private var gameDescription = ""
    @State private var showingAlert = false
    
    var body: some View {
        NavigationView {
            VStack {
                Form {
                    Section {
                        TextField("Game Name", text: $gameName)
                        TextField("Game Description", text: $gameDescription)
                    }
                    
                }
                
            }
            .navigationBarItems(
                leading:
                Button(action: {
                    self.presentationMode.wrappedValue.dismiss()
                }) {
                    Text("Cancel")
                }
                .padding(10)
                .foregroundColor(Color.white)
                .background(Color.red)
                ,
                
                trailing:
                Button(action: {
                    let newGame = Game(context: self.moc)
                    newGame.gameName = self.gameName
                    newGame.gameDescription = self.gameDescription
                    
                    do {
                        try self.moc.save()
                        self.presentationMode.wrappedValue.dismiss()
                    } catch {
                        print("Whoops! \(error.localizedDescription)")
                    }
                }) {
                    Text("Add Game")
                }
            )
        }
        
        
    }
}
struct AddGameView:View{
@环境(\.managedObjectContext)变量moc
@FetchRequest(实体:Game.entity(),sortDescriptors:[])var games:FetchedResults
@环境(\.presentationMode)变量presentationMode
@国家私有var gameName=“”
@国家私有var gameDescription=“”
@国家私有变量showingAlert=false
var body:一些观点{
导航视图{
VStack