SwiftUI: Error message when using .onMove on List built with forEach - swift

I have an array containing some data that I want to present in a View. It should be possible to rearrange the data by holding and dragging it to its new position. I have used the .onMove modifier on a List generated using ForEach to iterate over every element in the list. My code works exactly as expected, but throws the following error/warning:
2022-10-12 18:48:52.833139+0200 Playground[1212:207280]
[EventDispatcher] Found no UIEvent for backing event of type: 11;
contextId: 0xFEEA6094
This only happens when using an actual device (iPhone 12 Pro Max on iOS 16.0.2), not when using the simulator (Xcode Version 14.0.1 (14A400), build in simulator of any device that runs iOS 16).
The code (the whole project is way bigger, but this is enough to trigger the error/warning):
struct ContentView: View {
#State var stuffList = ["Beer", "Chips", "Boardgames"]
var body: some View {
NavigationStack {
List {
ForEach(stuffList, id: \.self) { stuff in
Text(stuff)
}
.onMove { stuffList.move(fromOffsets: $0, toOffset: $1) }
}
}
}
}
Edit:
I have now tried different code snippets from online tutorials, e.g. this one (Hacking in Swift) and I still get this message no matter what I try. As my code seems to work as intended, I will continue my project and treat this as "log noise". If someone knows more about this than I do or simply can confirm having the same issue, it would be highly appreciated.

Related

Typing in TextField moves cursor to end (macOS)

In macOS Ventura 13.0.1 and Xcode 14.1, I'm experiencing an issue where when I type in the beginning of a TextField, the cursor for some reason moves to the back.
I was able to reproduce it very simply:
struct ContentView: View {
#State private var text = "DEFG"
var body: some View {
NavigationSplitView {
Text("Sidebar")
} detail: {
VStack {
TextField("Text", text: $text)
}
}
}
}
To reproduce:
Open the app, and move the cursor to the start of the TextField. (so the insertion point is before the "D".
Type a letter, like "A", and the insertion point should jump to the end for some reason.
I have determined the cause is the VStack. For some reason, removing it fixes this issue entirely. However, in my real app, I do need the VStack as I have other elements too.
I wonder what's going on here. Is there some major oversight I have made? Or could this be an issue with SwiftUI?
If anyone is having trouble reproducing, I can upload a video.

SwiftUI - View Not Registering Input Data On Change

I created a View that displays a line graph based on an array of Doubles. The graph struct then divides the view horizontally in order for each of the points to have the same amount of separation. I am using GeometryReader and Path to make the graph. When I load the View with a given array of Doubles it displays correctly.
However, when the data changes, such as adding or removing data, the graph is not updated properly.
As an example using text, this is what the graph looks like normally (Assume it is a line graph): |-_-_-_-_|
When I add a value to the array of Doubles, the graph does appear to show that a new value was added, but the value is not recognized or read. This is what it looks like when a value is added (Again, assume it is a line graph): |-_-_-_-_ |. As you can see, it recognized there is a new value because it allocated space for the new value, but no line was shown, as it most likely does not recognize the added value. When I reload the view, such as by going back and into the view again, the graph is displayed correctly.
The big problem comes when a value is deleted. When a value is deleted, the app crashes with the error Fatal error: Index out of range. When I load the app again the graph is fixed.
I thought there might be something wrong with my deleting, so I created a test file in which I referenced an array of Doubles and buttons to add and remove values from the array, and the same behavior happened. This showed that the values put into the View were not updated properly.
This is the file I created to test the behavior of my graph:
struct GraphTest: View {
/*Data*/
#State var data: [Double] = [180, 242, 164, 202, 176, 100]
var body: some View {
VStack {
/*Struct that shows the line graph*/
LineGraph(data: data)
.frame(height: 200)
/*Button to remove the last item of array*/
Button(action: {
data.removeLast()
}) {
Text("Delete")
}
/*Button to add a value to the end of the array*/
Button(action: {
data.append(180)
}) {
Text("Add")
}
}
}
}
And this is how I'm setting up my LineGraph struct:
struct LineGraph: View {
var data: [Double]
var body: some View {
GeometryReader { geometry in
...
I tried doing data #Bindable in LineGraph, but I could not find a way to do so, as I'm getting the data from a Core Data FetchRequest, but I really do not know what to do from now to fix the issue, as I am relatively new in SwiftUI, and could not find anything similar on the internet.
Any help is appreciated, thank you :)
There is not enough code provided in LineGraph, but I assume you have inside something like
ForEach(0..<data.count) { i in // iterating this way result in crash !!
Text("\(self.data[i])")
}
instead you have to iterate at least like
ForEach(data.indices, id: \.self) { i in // no crash !!
Text("\(self.data[i])")
}

SwiftUI view sometimes creates Thread 1: EXC_BAD_ACCESS (code=1, address=0x6002005b8368), when I put array as a parameter

SwiftUI View file
struct NoteListView: View {
#EnvironmentObject var presenter: NoteListPresenter
var body: some View {
NavigationView{
AddNoteButton()
Text(presenter.noteViewModels[0].title)
}
}
}
struct NoteListView_Previews: PreviewProvider {
static var previews: some View {
NoteListView()
}
}
I first got this error when I finished writing the logic and started to writing Views. After add my custom button AddNoteButton() to main view, it gave the following error, although it worked before I added this button. I tried to rewrite my views, but although it works at the beginning at some random point of time it throws this error again(by other words sometimes it works, but when i add some irrelevant code it stops working and discarding changes doesn't solve the problem). It always highlights line, where I use noteViewModels array inside of the NoteListView.
Also I added method which prints array to presenter and it always prints everything.
func printAll(){
for element in self.noteViewModels{
print(element.title)
}
}
I can not add other files to question, because there is too many of them. But i hope that I gave enough information, If you think that there is not enough information you are free to ask me or you can check out github:
https://github.com/ShynggysSaparbek/ViperNotesWithRealm/
Xcode version 11.3
Mac OS version Catalina 10.15.2

Why is my SwiftUI List row not always updating internally

I have a list of reminders grouped into sections by completion and date. With data coming from an ObservedObject DataStore called global. I pass a realmBinding to the cell. The cell can update this binding and it will trigger the data store to update.
List {
// Past Due
if self.global.pastDueReminders.count > 0 {
Section(header: SectionHeader {}){
ForEach(self.global.pastDueReminders) { reminder in
NavigationLink(destination: ReminderDetail( reminder: reminder.realmBinding())) {
GeneralReminderCell(reminder: reminder.realmBinding())
}
}
}
}
// Completed
if self.global.completeReminders.count > 0 {
// Same as PastDue but for Completed
}
}
The cell looks something like:
struct GeneralReminderCell: View {
#Binding var reminder:Reminder
var body: some View {
HStack(alignment:.top, spacing: 10) {
Image(systemName: reminder.completed ? "checkmark.circle.fill" : "circle")
.onTapGesture(perform:{ self.reminder.completed = !self.reminder.completed })
VStack(alignment: .leading, spacing: 2) {
Text("Follow up with \(reminder.client.fullName)").fontWeight(.semibold)
if reminder.title.count > 0 {
Text(reminder.title)
}
Text(reminder.date.formatted()).foregroundColor(.gray)
}
}.padding(.vertical, 10)
}
}
When tapping on an image it toggles the reminder completion state and its position changes in the List view. The image that was tapped should changed to a filled in check when completed.
This behaviour almost always happens as expected, but sometimes the checked image will get out of sync with the completed state of reminder. I've look at this for quite some time and have not made much headway. Why is the checked image not always matching the state of the data?
Even though this is a very old question, I may have been working on what appears to be this same problem. In my case, my App is running on macOS. At first, the problem also seemed to be very intermittent and had been difficult to reproduce consistently.
I also have a View with a ForEach supplying rows to a List. My row's View contains an #State for an Optional Image that gets updated several different ways via actions performed by that same row View (e.g. Continuity Camera, file picker or drag & drop). The issue is that sometimes the new Image is shown and sometimes it is not shown. Using Self._printChanges() I am able to see that the #State is changing and the row's body it is being redrawn, however, the rendered View does not change. The only pattern that I am able to observe is that this issue only seems to occur with the last row in the List. Based on the success of my workaround below, it seems to confirm that there is an issue with the way SwiftUI's List reuses table cells.
My solution/workaround is to replace:
List {
ForEach {
}
}
With:
ScrollView {
LazyVStack {
ForEach {
}
}
}

SwiftUI - NavigationView Error message - Argument passed to call that takes no arguments

I am trying to implement a really basic NavigationView in SwiftUI. When I try the sample code that I have seen on other websites it generates an error message in Xcode. I am not sure why or how to fix this.
I have tried to clean the project, quit Xcode-Beta and restart it but that did not work.
struct ContentView : View {
var body: some View {
NavigationView {
Text("This is a great app")
}
}
}
I thought the code above should work but the error I get says:
"Argument passed to call that takes no arguments."
Any ideas or suggestions?
VStack can only take 10 argument.
If more, there will be error, so you should make it nested.
from
VStack{
}
to
VStack{
VStack{
}
VStack{
}
}
I had this same error message too and figured out what I did wrong and then kind of felt like an idiot. Ha ha.
Take a look:
It took me a while to figure out that my struct was the same name as a previously defined struct VStack. Whoops!
So I'm wondering if you had a file in your project that did this too.
check-in your app is there any Swifui class with the name NavigationView.
also when you jump to the definition from NavigationView it should refer to:
#available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 7.0, *)
public struct NavigationView<Content> : View where Content : View {
public init(#ViewBuilder content: () -> Content)
/// The type of view representing the body of this view.
///
/// When you create a custom view, Swift infers this type from your
/// implementation of the required `body` property.
public typealias Body = Never
}
Testing Xcode 11.2.1 and it's still buggy. I noticed when I keep adding primitive views to my ContentView, I start getting errors like
"Argument passed to call that takes no arguments",
"Type of expression is ambiguous without more context" etc. on primitive views which worked before.
When I replaced, for example,
ScrollView {
VStack {
Text
Button
Image
Text
Button
Image
Text
Button
Image
...
}
}
with
ScrollView {
VStack {
VStack {
Text
Button
Image
}
VStack {
Text
Button
Image
}
VStack {
Text
Button
Image
}
...
}
my code started to compile and run again.
I found this problem when I accidentally try to redefine Text struct. Check if you naming your custom class the same as those in SwiftUI.
#Matteo Pacini helped me find the answer. When I started a new Xcode Project just to test the code above everything worked. I had a lot of files and was testing a lot of different code while experimenting with SwiftUI in my other project and for some reason XCode was always generating this error.
When I tried everything in a new project it worked. Something to be aware of while testing. Hope this helps others avoid similar problems.
Embed the 'Text("This is a great app")' in a VStack
struct ContentView : View {
var body: some View {
NavigationView {
Stack {
Text("This is a great app")
}
}
}
}