Post

Replies

Boosts

Views

Activity

EditView Reference is Broken
I've made a simplified version of what I'm trying to do in the included code, but basically I'm trying to make a view that edits a data model. This edit view shows up when a button in a context menu is clicked. The problem is no matter which one I open up the context menu on it always opens up whichever one I clicked first. The reference to the object in the .sheet never changes. How can I fix this?? Example Code: import SwiftUI class Object: Identifiable{     var id: UUID?     var title: String     var string: String        init(title: String, string: String) {         self.id = UUID()         self.title = title         self.string = string     } } struct ContentView: View {     @State private var showingEditView = false     @State private var objectList = [Object(title: "First", string: "Editor"), Object(title: "Second", string: "Addition"), Object(title: "Third", string: "Twelve")]     var body: some View {         NavigationView{             List{                 Section("Objects"){                     ForEach(objectList) { object in                         NavigationLink(destination: ObjectView(obj: object)){                             Text(object.title)                         }                         .sheet(isPresented: $showingEditView){                             EditView(obj: object)                         }                     }                 }                 .contextMenu{                     Button(action: {                         self.showingEditView.toggle()                     }){                         Text("Edit Item")                     }                 }             }             .listStyle(InsetGroupedListStyle())             .cornerRadius(10)             .navigationBarTitle("My List")         }     } } struct ContentView_Previews: PreviewProvider {     static var previews: some View {         ContentView()     } } struct ObjectView: View {     @State var obj: Object     var body: some View {         NavigationView{             VStack{                 Text(obj.string)             }             .navigationBarTitle(obj.title)         }     } } struct EditView: View {     @Environment(\.dismiss) var dismiss     @State var obj: Object     @State var word = ""     var body: some View {         NavigationView{             Form{                 TextField("Change Word", text: $word)                     .onAppear(perform: {                         word = obj.string                     })             }             .navigationBarItems(trailing:             Button(action: {                     dismiss()             }){                 Text("Done")                     .bold()             })         }     } } Any help would be greatly appreciated. All the best!
2
0
423
Jun ’22
Dismissing a Sheet That Doesn't Call Another View
I need to dismiss a sheet that doesn't call a view inside of it instead it makes it's own view. The reason this is necessary is because the view changes an attribute of an object in the previous view which won't update unless the attribute is changed in the same struct. Is there any way I could dismiss the view without swiping down in this way? Or a way I can pass a reference to the attribute so that when I change it in a separate struct it will update live in a previous one I'm sorry for my super confusing explanation. I've simplified my actual implemented code to the following: struct ContentView: View {     @Environment(\.dismiss) var dismiss     @State var word = ""     @State private var isSheetShowing = false     var body: some View {         NavigationView{             Form{                 TextField("Change Word", text: $word)                 Button(action: {                     isSheetShowing.toggle()                 }){                     Text("Done")                         .bold()                 }                 .sheet(isPresented: $isSheetShowing){                     NavigationView{                         List{                             Text("Hello User")                         }                         .navigationBarItems(leading:                                                 Button(action: {                             dismiss()                         }){                             Text("Cancel")                                 .bold()                         })                     }                 }             }         }     } } Pressing cancel in the sheet does not dismiss the view as I want it to.
2
0
506
Jun ’22
Calendar with Correlating Data. Please Help!!!
Basically I need a view with a calendar that will show data attributes from the item. I've tried two different approaches both have their listed problems. There must be a better way to do something like this. Surely it's not ideal to create a new item every time a date is opened or constantly check if something is there, but I don't know any other way. Actual View: import SwiftUI import CoreData struct ContentView: View {     @Environment(\.managedObjectContext) var managedObjContext     @Environment(\.calendar) var calenda     @Environment(\.dismiss) var dismiss     @FetchRequest(sortDescriptors: [], predicate: NSPredicate(format: "timestamp == %@", Date.now as CVarArg)) var items: FetchedResults<Item>          @State private var date = Date.now          var body: some View {         NavigationView{             VStack{                 DatePicker("Calendar", selection: $date, in: Date.now...,displayedComponents: [.date])                     .datePickerStyle(.graphical)                     .onAppear(perform: {                         if (items.isEmpty){                             PersistenceController().addItem(date: date, context: managedObjContext)                         }                     })                     .onChange(of: date){ value in                         items.nsPredicate=NSPredicate(format: "timestamp == %@", date as CVarArg)                         if (items.isEmpty){                             PersistenceController().addItem(date: date, context: managedObjContext)                         }                     }                 if (!items.isEmpty){ //This is the only difference in the two approaches. I just put either one of the next two blocks of code in here                 }             }             .navigationBarTitle("My Planner")         }     }          func getTitle(date: Date)->String{         let formatter = DateFormatter()         formatter.dateStyle = .medium         return formatter.string(from: date)     } } First (looks correct, but doesn't show the changes live): PlannedMealsView(item: items[0]) Spacer() //And then this is added at the bottom struct PlannedMealsView: View {     @Environment(\.managedObjectContext) var managedObjContext     @State var item: Item     var body: some View {             VStack{                 Text(item.timestamp ?? Date.now, style: .date)                     .font(.title2)                     .bold()                 Section("Word"){                     if(item.word != nil){                         HStack{                             Spacer()                             Text(item.word!)                             Spacer()                             Button(action: {                                 PersistenceController().removeFromItem(item: item, context: managedObjContext)                             }){                                 Image(systemName: "minus.circle").bold()                             }                             Spacer()                         }                     } else {                         Button(action: {                             PersistenceController().addToItem(item: item, context: managedObjContext)                         }){                             Image(systemName: "plus.circle").bold()                                 .padding(.vertical, 10)                                 .padding(.horizontal, 20)                         }                     }                 }                 Spacer()             }             .frame(height:200)     } } Second (allows direct access to the objects data, but bugs after 5 or 6 date changes): VStack{                             Text(items[0].timestamp ?? Date.now, style: .date)                                 .font(.title2)                                 .bold()                             Section("Word"){                                 if(items[0].word != nil){                                     HStack{                                         Spacer()                                         Text(items[0].word!)                                         Spacer()                                         Button(action: {                                             PersistenceController().removeFromItem(item: items[0], context: managedObjContext)                                         }){                                             Image(systemName: "minus.circle").bold()                                         }                                         Spacer()                                     }                                 } else {                                     Button(action: {                                         PersistenceController().addToItem(item: items[0], context: managedObjContext)                                     }){                                         Image(systemName: "plus.circle").bold()                                             .padding(.vertical, 10)                                             .padding(.horizontal, 20)                                     }                                 }                             }                         Spacer()                     }                     .frame(height:200) Unchanged Files: Persistence- import CoreData struct PersistenceController {     static let shared = PersistenceController()     let container: NSPersistentContainer     init(inMemory: Bool = false) {         container = NSPersistentContainer(name: "Test")         if inMemory {             container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")         }         container.loadPersistentStores(completionHandler: { (storeDescription, error) in             if let error = error as NSError? {                 fatalError("Unresolved error \(error), \(error.userInfo)")             }         })         container.viewContext.automaticallyMergesChangesFromParent = true     }          func addItem(date: Date, context: NSManagedObjectContext){         let item = Item(context: context)         item.timestamp = date         item.word = nil                  save(context: context)     }          func addToItem(item: Item, context: NSManagedObjectContext){         item.word = "Test"                  save(context: context)     }          func removeFromItem(item: Item, context: NSManagedObjectContext){         item.word = nil                  save(context: context)     }          func save(context: NSManagedObjectContext){         do {             try context.save()         } catch {             let nsError = error as NSError             fatalError("Unresolved error \(nsError), \(nsError.userInfo)")         }     } } Data Model- If you have any questions I'll be happy to answer. Any help is greatly appreciated. All the best!
2
0
1.6k
Jun ’22
Combine Duplicate Items in an Array
I have an object called Item with two attributes, name (String) and value (Double). Given an array of Items I need combine the values of all items with the same name and keep the items with no duplicates. For example, say there were 4 items in the array and two of them named "Test" and the others "Object" and "Item". "Object" and "Item" would remain in the list, but the values of the two "Test"s would be combined into one item with the same name "Test". I've included the following code for a visual representation. Delete the comments as you read them to clean up. They're just there to clear up any confusion. Leave a comment if you have any questions. Thanks for the help! Content View: import SwiftUI import CoreData struct ContentView: View {     @Environment(\.managedObjectContext) var managedObjContext     @ObservedObject var persistence = PersistenceController.shared     @State private var items = PersistenceController.shared.getItems()          @State var isAddViewShowing = false     var body: some View {         NavigationView{             List{                 Section{                     ForEach(items) { item in //Displays the list of items                         HStack{                             Text(String(item.name!))                             Spacer()                             Text(String(Int(item.value)))                         }                     }                     .onDelete(perform: { indexSet in                         deleteItem(indexSet: indexSet)                     })                 }             }             .navigationBarTitle("Items")             .navigationBarItems(leading: combineItemsButton, trailing: addButton)             .sheet(isPresented: $isAddViewShowing){ //displays the view to add an item                 AddView()                     .onDisappear(perform: {                         items = persistence.getItems() //"refreshes" the list of items                     })             }         }     }          var combineItemsButton: some View{         Button(action:{ //combine duplicates here             persistence.contextSave()             items = persistence.getItems()         }){             Text("Combine Duplicates")                 .bold()         }     }          var addButton: some View{         Button(action:{             isAddViewShowing.toggle()         }){             Text("Add Item")                 .bold()         }     }          func deleteItem(indexSet: IndexSet){         withAnimation{             indexSet.map {                 items[$0]             }             .forEach(managedObjContext.delete)                          persistence.contextSave()             items = persistence.getItems()         }     } } Add View: struct AddView: View{     @Environment(\.dismiss) var dismiss     @ObservedObject var persistence = PersistenceController.shared          @State var name: String = ""     @State var value = ""     @State private var alertMessage = ""     @State private var showAlert = false     var body: some View{         NavigationView{             Form{                 TextField("Item Name", text: $name)                 TextField("Item Value", text: $value)                     .keyboardType(.decimalPad)             }             .navigationBarTitle("Add Item")             .navigationBarItems(leading: dismissButton, trailing: submitButton)         }     }     var submitButton: some View{         Button(action: {             if (name == ""){ //ensures the item has a name                 alertMessage="Your recipe needs a name"                 showAlert.toggle()             } else {                 persistence.addItem(name: name, value: Double(value) ?? 2)                 dismiss()             }         }){             Text("Submit")                 .bold()         }         .alert(alertMessage, isPresented: $showAlert){             Button("OK",role: .cancel){}         }     }          var dismissButton: some View{         Button(action: {             dismiss()         }){             Text("Cancel")                 .bold()         }     } } Persistence File: import CoreData class PersistenceController : ObservableObject{     static let shared = PersistenceController()     let container: NSPersistentContainer          init(inMemory: Bool = false) {         container = NSPersistentContainer(name: "Test")         if inMemory {             container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")         }         container.loadPersistentStores(completionHandler: { (storeDescription, error) in             if let error = error as NSError? {                 fatalError("Unresolved error \(error), \(error.userInfo)")             }         })         container.viewContext.automaticallyMergesChangesFromParent = true     }          func getItems() -> [Item] { //fetches items         let context = container.viewContext         var request = NSFetchRequest<Item>()         request = Item.fetchRequest()         request.entity = NSEntityDescription.entity(forEntityName: "Item", in: context)         do {             let items = try context.fetch(request)             if items.count == 0 { return []}             return items.sorted(by: {$0.name! > $1.name!})         } catch {             print("**** ERROR: items fetch failed \(error)")             return []         }     }          func addItem(name: String, value: Double){         let context = container.viewContext         let item = Item(context: context)         item.id = UUID()         item.name = name         item.value = value                  contextSave()     }          func contextSave() {         let context = container.viewContext         if context.hasChanges {             do {                 try context.save()                 self.objectWillChange.send()             } catch {                 print("**** ERROR: Unable to save context \(error)")             }         }     } } Data Model:
2
0
2.1k
Jun ’22
Core Data
So I was just following along with CodeWithChris's video on make a persistent data storage (https://youtu.be/O7u9nYWjvKk) and I got to the part where he says to include the subclass NSManagedObject to the family and person classes. I have a very similar program with recipe and list of recipes, but when I add "NSManagedObject" I get an error: < unknown >:0: error: stored property '_title' requires an initial value CoreData.NSManagedObject:2:12: note: superclass 'NSManagedObject' requires all stored properties to have initial values open class NSManagedObject : NSObject { < unknown > :0: error: stored property '_calories' requires an initial value CoreData.NSManagedObject:2:12: note: superclass 'NSManagedObject' requires all stored properties to have initial values open class NSManagedObject : NSObject { etc. Unsure of how to fix it. Any help would be greatly appreciated. Code in case I'm missing something RecipeList: import Foundation import CoreData class RecipeList:NSManagedObject, Identifiable{     @Published var recipeList:[Recipe]     init(){         recipeList=[]     }     func addRecipe(recipe: Recipe){         self.recipeList.append(recipe)     }     func removeRecipe(loc: Int){         self.recipeList.remove(at: loc)     }     func getList() -> Array<Recipe>{         return recipeList     } } Recipe: import Foundation import UIKit import CoreData class Recipe:NSManagedObject, Identifiable{     @Published var title: String     @Published var calories: String     @Published var ingredients: Array<String>     @Published var instructions: Array<String>     @Published var totalTime: String     @Published var notes: String     init(title: String, calories: String, ingredients: Array<String>, instructions: Array<String>, totalTime: String, notes: String){         self.title=title         self.calories=calories         self.ingredients=ingredients         self.instructions=instructions         self.totalTime=totalTime         self.notes=notes     } }
0
0
369
May ’22
Toolbar Above Keyboard
I would like to implement the “Toolbar” kind of thing above the keyboard shown in the image that includes an up and down arrow to iterate through text fields and a done button to dismiss the keyboard. How do I do this? Thanks!
0
0
339
May ’22
Nav View inside Nav View in a Sheet
So I have a sheet View for when I add a recipe to my program, but when I add an instruction I want the user to be able to click their entry and check it to see if it is correct so what I’ve done is add a text view to enlarge it, but when I go to the view it shows the nav bar of the previous view like this: This only happens when I use a sheet.
1
0
402
May ’22
Button That Changes Label on Click
So I’ve looked this up so many times and tried every way I’ve found using a @State variable and nothing works. I need a button that toggles between SystemImage: “Star” to SystemImage: “Star.fill” when clicked. And I want it to happen when it’s clicked. Everything I’ve tried only changes when I close and reopen the view because it happens on appearance. Is there any way to make it change instantly? Thanks for any help!
1
0
402
May ’22
Searching with @FetchRequest
So I've made a function using FetchRequest to search, but im getting an error: "Accessing StateObject's object without being installed on a View. This will create a new instance each time." The function takes a string and searches the core data for objects containing that string. The string is obtained from a .searchable object and the function is ran as a ForEach parameter. This is the function: func searchResults(searchingFor: String) -> FetchedResults<Recipe> {         @FetchRequest(sortDescriptors: [SortDescriptor(\.date, order: .reverse)], predicate: NSPredicate(format: "title CONTAINS[c] %@",searchingFor)) var searchRecipes: FetchedResults<Recipe>         return searchRecipes     } Is there a better way to do this or can I do it this way and tweak it a little bit? I really just need to have a search bar that returns a FetechedResults type so I can use it in a ForEach loop. Any help is greatly appreciated.
3
0
709
Jun ’22
Dynamically Filtering a FetchRequest
I am trying to implement a search bar in my recipe storage app. I got recommended using the .filter function that I didn’t know could be used on FetchedResults. So I did and now I’m getting errors, but not ones saying that it isn’t in the scope so I believe this is possible, just now sure how. The ForEach loop containing the filter: •ForEach(recipes.filter({$0.title.contains(searchingFor)})) { recipe in Note: Recipes is just a FetchedResults type and searchingFor is just a string that comes from the search bar. The errors: •Value of optional type 'String?' must be unwrapped to refer to member 'contains' of wrapped base type 'String' •Chain the optional using '?' to access member 'contains' only for non-'nil' base values •Force-unwrap using '!' to abort execution if the optional value contains 'nil' Any help is greatly appreciated.
1
0
1.2k
Jun ’22
Default Keyboard Toolbar
Whenever I open a text field almost anywhere I get this common toolbar above my keyboard with two arrows that iterate through text fields and a done button. Not just on Apple related things, but even when I search on google. Which leads me to believe this is a default object and that google did not take the time to make an identical keyboard toolbar as all of Apple’s. So how do I get this default toolbar? toolbar:
1
0
917
Jun ’22