After adding an element to an array, the List displaying its data is refreshed, the last element is always selected (according to the sort order) and not the last inserted element, even if I update the selection variable programmatically in the addItem method. To better track the issue, I added an .onChange event handler in which it is possible to observe that after the insertion of a new element, the selection variable changes twice. I prepared a sample project as a variant of the template provided by Xcode for MacOS App with CoreData. You can replace the ContentView of the template with the one below. Thank you.
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: false)],
animation: .default)
private var items: FetchedResults<Item>
@State var counterSel:Int = 0
@State var selection:Item?
var body: some View {
NavigationSplitView {
List(Array(items), id:\.id, selection: $selection) { item in
NavigationLink(value: item) {
Text(item.timestamp!, formatter: itemFormatter)
}
}
} detail: {
if let _ = selection {
Text("Item at \(selection!.timestamp!, formatter: itemFormatter)").id(selection)
}
}
.toolbar {
ToolbarItem {
Button(action: addItem) {
Label("Add Item", systemImage: "plus")
}
}
}
.onChange(of: selection) { oldValue, newValue in
counterSel += 1
print("Counter: \(counterSel)")
if let _ = newValue {
print("Id: \(newValue!.objectID)")
}
}
}
private func addItem() {
withAnimation {
let newItem = Item(context: viewContext)
newItem.timestamp = Date()
do {
try viewContext.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
selection = newItem
}
}
private func deleteItems(offsets: IndexSet) {
withAnimation {
offsets.map { items[$0] }.forEach(viewContext.delete)
do {
try viewContext.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
}
}
}
private let itemFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .short
formatter.timeStyle = .medium
return formatter
}()
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Hi all,
with the below code I get
How can I hide the gray angles?
Thank you for your help.
NavigationView {
ZStack {
RoundedRectangle(cornerRadius: 10)
.foregroundColor(Color(red: 0.283, green: 0.481, blue: 0.658))
.shadow(radius: 10)
.overlay(
RoundedRectangle(cornerRadius: 15)
.stroke(Color(hue: 0.579, saturation: 0.0, brightness: 0.9), lineWidth: 2)
)
List (
driversArr,
id:\.self,
selection: $selection) {
currentDriver in
NavigationLink {
RiskDriverDetailsView(theDriver: currentDriver)
} label: {
Label(currentDriver.wrappedName, systemImage: "point.filled.topleft.down.curvedto.point.bottomright.up")
}
.foregroundColor(.white)
}
.scrollContentBackground(.hidden)
}
.background(Color(.clear))
}
Hi all,
can someone explain me while in this playground code
import Foundation
let arr:Array<Int> = [1,3,5,7,9,11]
let exc:Array<Int> = [3,7,11]
let newarr = arr.drop { exc.contains($0) }
let newarr2 = arr.filter { !exc.contains($0) }
print(newarr)
print(newarr2)
the drop function return the whole array (don't drop anything) while the filter one give the right result?
Thank you
I have a problem with the binding of a picker. Here a short sample project.
A simple data structure with two fields: a string (f1) and an enum (f2).
struct D0: Identifiable,Equatable {
var id: UUID
var f1:String
var f2:T0
}
extension D0 {
struct Data {
var f1:String = String()
var f2:T0 = .s1
}
var data:Data {Data(f1: f1, f2: f2)}
init(data:Data) {
self.id = UUID()
self.f1 = data.f1
self.f2 = data.f2
}
mutating func update(from data:Data) {
self.f1 = data.f1
self.f2 = data.f2
}
static let sampleData : [D0] = [
D0(id: UUID(), f1: "string1", f2: .s1),
D0(id: UUID(), f1: "string2", f2: .s2)
]
enum T0: Int,CaseIterable,Identifiable {
case s1=1
case s2
var id:Self {self}
var name:String {
switch rawValue {
case 1:
return "one"
case 2:
return "two"
default:
return "undefined"
}
}
In the Editing View the string is bound to a textfield while the enum field is bound to the selection of a Picker.
struct Editing: View {
@Binding var data:D0.Data
var body: some View {
Form {
VStack {
TextField("F1", text: $data.f1)
Picker("F2", selection: $data.f2) {
ForEach(T0.allCases) { t0 in
Text(t0.name)
.tag(t0)
}
}
}
}
}
}
Data are presented in a list with three sections:
data from the binding to the whole data
subset of data having f2 equal to .s1
subset of data having f2 equal to .s2
struct mList: View {
@Binding var all:[D0]
func segmentByState(state:T0) -> [D0] {
return all.filter { d in
d.f2 == state
}
}
var body: some View {
List {
Section("All") {
ForEach($all) { $a in
NavigationLink(destination: {
Details(d0: $a)
}) {
Cell(d0: a)
}
}
}
Section("S1") {
ForEach(segmentByState(state: .s1)) { a in
//look for the index of the object in the binding
let ind:Int = all.firstIndex(of: a)!
NavigationLink(destination: {
// pass the bound element
Details(d0: $all[ind])
}) {
Cell(d0: a)
}
}
}
Section("S2") {
ForEach(segmentByState(state: .s2)) { a in
//look for the index of the object in the binding
let ind:Int = all.firstIndex(of: a)!
NavigationLink(destination: {
// pass the bound element
Details(d0: $all[ind])
}) {
Cell(d0: a)
}
}
}
}
}
}
Changing the f2 value move the rows in the right section (2 or 3) but its name is updated only in the first section while in the others it remains the previous one.
Changing the f1 value it works correctely,
How should I bound data to have the name correctly presented?
Thank you.
Hi, I'm using Xcode 12.3 on Big Sur Beta 11.2 and my project has deployment target Mac OS 11.
In my project I trained a MLTextClassifier
let classifier = try MLTextClassifier(trainingData: trainingData,
textColumn: "NLTokens",
labelColumn: "classLabel")
I imported the model in the app and I can use it only referring as the class of the model.
let myInstance = classifier()
In particular I can see that in the MLTextClassifier class there is the predictionWithConfidence method but if I try to use it I get a build error.