Posts

Post not yet marked as solved
4 Replies
825 Views
I have made a demo app reproducing the issue I am facing with the iPad when using the DoubleColumnNavigationViewStyle My normal navigation path is: List1 -> Form1 -> Form2 -> Picker1 -> (change the Teacher) Somehow Form1s are injected and the path becomes: List1 -> Form1 -> (Form1, etc...) -> Form1 -> Form2 -> Picker1 -> (change the Teacher) I do not have NavigationLinks from From1 to Form1 anywhere in my code. A new Form1 is inserted just by changing a value of a Picker I believe this is a bug More moments are in the code ContentView.swift - https://developer.apple.com/forums/content/attachment/15890515-fe87-460b-9f1b-9947eaf2cfd0
Posted
by Blinker73.
Last updated
.
Post not yet marked as solved
1 Replies
285 Views
Hello, I recently asked a question on the forum and while I am waiting for replies, I would like to look at recently posted questions and try to help other users. Unfortunately I cannot find a way to obtain a list of recently posted questions ordered by date (most recent first). I think this would be useful to the community, Regards,
Posted
by Blinker73.
Last updated
.
Post marked as solved
4 Replies
2.2k Views
Hi, I am new to developpement in xcode and am trying to build my first app in SwiftUI.I am struggling with multi selection in a list of CoreData Items.I build an application comparing the functionality when using an Array versus when using CoreDataThe Array tab is working as I expect but the Core data tab is not.Am I doing something wrong or is it a bug?You can see further details/comments in the code.Thanks, import SwiftUI // ######################################################################################## // XCode // Version 11.4.1 (11E503a) // Simulator // Version 11.4.1 (921.9) // SimulatorKit 581.9.1 // CoreSimulator 704.12.1 // Device // iPhone SE (2nd generation) // ######################################################################################## // ######################################################################################## // the CoreData entity is named MyNumber // I don't think extending it as Identifiable has any effect but it shouldn't hurt to add it // ######################################################################################## extension MyNumber: Identifiable { // ######################################################################################## // the entity has these two fields // @NSManaged public var id: UUID? // @NSManaged public var stringValue: String? // ######################################################################################## } struct ContentView: View { // Tab variables @State private var tabSelection = 0 // Array variables @State var arrayNumbers = ["One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten"] @State var arrayEditMode = EditMode.inactive @State var arraySelection = Set<String>() // Core Data variables @State var cdEditMode = EditMode.inactive // ######################################################################################## // Am I using the correct type ? Set<MyNumber>() : I also tried Set<UUID>() without success // ######################################################################################## // # Using Set<MyNumber>() @State var cdSelection = Set<MyNumber>() // ######## OR ############ // # Using Set<UUID>() // @State var cdSelection = Set<UUID>() // ##################################################################### @Environment(\.managedObjectContext) var moc @FetchRequest(entity: MyNumber.entity(), sortDescriptors:[]) var cdNumbers: FetchedResults<MyNumber> var body: some View { TabView(selection: $tabSelection){ // Array Tab VStack{ Text("Array").font(.largeTitle) NavigationView { List(selection: $arraySelection) { ForEach(arrayNumbers, id: \.self) { number in Text(number) } .onDelete(perform: arrayOnSwipeDelete) } .navigationBarTitle("Selected count \(arraySelection.count)") .navigationBarItems(leading: arrayDeleteButton, trailing: EditButton()) .environment(\.editMode, self.$arrayEditMode) } } .tabItem { VStack { Image(systemName: "checkmark") Text("Array") } } .tag(0) // Core Data Tab VStack{ VStack{ Text("Core Data").font(.largeTitle) Button("Add coredata numbers") { for number in self.arrayNumbers { let cdNumber = MyNumber(context: self.moc) cdNumber.id = UUID() cdNumber.stringValue = "\(number)" } try? self.moc.save() }.disabled(cdEditMode.isEditing) } NavigationView { List(selection: $cdSelection) { ForEach(cdNumbers, id: \.id) { number in Text(number.stringValue ?? "NULL") } // ##################################################################### // Problem #1 // Without the onDelete, the left selection column does not appear at all // To reproduce this // 1 - click "Add coredata records" // 2 - Click "Edit" // ##################################################################### // Problem #2 // With the onDelete, rows can be selected but $cdSelection stays empty // To reproduce this // 1 - click "Add coredata records" // 2 - Click "Edit" // 3 - Select records (notice the selection count is not updated) // 4 - Even with some selected records, the trashcan stays disabled because of the disabled event // 5 - Commenting out the disabled event and clicking on the trashcan should delete records but it does nothing // ##################################################################### .onDelete(perform: cdOnSwipeDelete) } .navigationBarTitle("Selected count \(cdSelection.count)") .navigationBarItems(leading: cdDeleteButton, trailing: EditButton()) .environment(\.editMode, self.$cdEditMode) }} .tabItem { VStack { Image(systemName: "xmark") Text("CoreData") } } .tag(1) } } init() { // Global Navigation bar customizations UINavigationBar.appearance().largeTitleTextAttributes = [ .font : UIFont.systemFont(ofSize: 18, weight: UIFont.Weight.bold)] } // array functions private var arrayDeleteButton: some View { return Button(action: arrayDeleteNumbers) { if arrayEditMode == .active { Image(systemName: "trash") } }.disabled(arraySelection.count <= 0) } private func arrayDeleteNumbers() { for id in arraySelection { if let index = arrayNumbers.lastIndex(where: { $0 == id }) { arrayNumbers.remove(at: index) } } arraySelection = Set<String>() } // ##################################################################### // Array selecction is not affected by the presence of the arrayOnSwipeDelete function // ##################################################################### private func arrayOnSwipeDelete(with indexSet: IndexSet) { indexSet.forEach { index in arrayNumbers.remove(at: index) } } // Core Data Functions private var cdDeleteButton: some View { return Button(action: cdDeleteNumbers) { if cdEditMode == .active { Image(systemName: "trash") } // ##################################################################### // Even with a commented .disable rule, the trash can deletes nothing // ##################################################################### }.disabled(cdSelection.count <= 0) } private func cdDeleteNumbers() { for selectedItem in self.cdSelection{ // ##################################################################### // # Using Set<MyNumber>() self.moc.delete(selectedItem) // ######## OR ############ // # Using Set<UUID>() // self.moc.delete(cdNumbers.first(where: {$0.id == selectedItem})!) // ##################################################################### } try? self.moc.save() // ##################################################################### // # Using Set<MyNumber>() cdSelection = Set<MyNumber>() // ######## OR ############ // # Using Set<UUID>() // cdSelection = Set<UUID>() // ##################################################################### } // ##################################################################### // Core data selecction is affected by the presence of the cdOnSwipeDelete function // IE: The selection column is shown in edit mode only if // this functuion is referenced by ForEach{}.onDelete() // ##################################################################### private func cdOnSwipeDelete(with indexSet: IndexSet) { indexSet.forEach { index in let number = cdNumbers[index] self.moc.delete(number) } try? self.moc.save() } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
Posted
by Blinker73.
Last updated
.