The workaround of writing the entire literal seems to work when assigning the color to a variable or constant, at least in Xcode 15.2 (15C500b). However, be aware that if the # isn't initially omitted from #colorLiteral, you'll be typing blind for a while.
But it doesn't work in all contexts, for example it does not work when trying to use a color literal to set the background color of a view.
struct myView: View {
var body: some View {
Text("Hello world!")
.background(Color(#colorLiteral(red: 0.3, green: 0.1, blue: 0.2, alpha: 1.0))) // shows as text
}
}
An additional workaround is to first assign the color to a constant, then use that constant.
struct anotherView: View {
let bgColor = Color(#colorLiteral(red: 0.3, green: 0.1, blue: 0.2, alpha: 1.0)) // shows as a color swatch
var body: some View {
Text("Hello world!")
.background(bgColor)
}
}
Post
Replies
Boosts
Views
Activity
Crashes like this in memory management code (e.g., malloc) are usually caused by writing past the beginning or end of an array. They can also be caused other ways, such as reusing memory that has been freed or changing the size of a struct or class and not recompiling all code that uses that struct or class.
In cases like this, it's often a good idea to clean the build environment (Product -> Clean build folder...) and see if that resolves the problem. If not, it's possibly a buffer overrun or underrun.
In this particular case, it looks like a bezier curve is being drawn. You might want to make sure that you are not writing to positions before the beginning of after the end of your control point array.
The memory corruption may also be caused by other threads, and may not be directly related to the thread that is crashing. More information about how to trigger this crash would be needed in order to be more specific.
As previously mentioned, SwiftUI Circles use the center of the screen as their origin, where project(_:) uses the upper-left corner of the screen as the origin. This offset is confusing, but unrelated to understanding how to use convert(position:from:), convert(position:to:), and project(_:).
While it has previously been noted that to get a world space coordinate for use with project(_:), the referenceEntity passed to convert(position:to:) needs to be nil. Looking closer at the description of convert(position:to:), it also says that the point is converted, "from the local space of the entity on which you called this method". Since the entity on which convert(position:to:) is being called on is the sphere object itself, the sphere's position will be the origin of that local space.
There are two ways to fix this. The first is to continue to call convert(position:to:) on object but pass the coordinate [0,0,0] instead of object.position, since an object's position is the origin of its local coordinate space. The other way is to convert object.position using the object's parent's convert(position:to:) method.
In both cases the line that need to be changed is:
let worldCoordinate = object.convert(position: object.position, to: nil) // Incorrect
One way to fix it:
let worldCoordinate = object.convert(position: [0,0,0], to: nil) // Fix 1
An alternate fix:
let worldCoordinate = object.parent?.convert(position: object.position, to: nil) // Fix 2
With either of these modifications and the previously mentioned framingOffset fix, the red marker circles do correctly follow all of the blue spheres.
I am still left with my original question though; Is there better documentation somewhere on how to do this conversion?
While playing around with just a single sphere and its marker circle, it seemed to be the case that when the sphere was in the upper-left corner (i.e., near coordinate 0,0, according to the printed output), the marker circle was near the center of the screen. Similarly, when the sphere was near the center of the screen, the marker circle was in the lower-right corner of the screen.
After consulting some sample code, to see if there might be any functions that are used to adjust for this unexpected offset, nothing seemed obvious.
Then I noticed that SwiftUI's Circle is described as, "centered on the frame of the view containing it". So, when it is at offset 0,0, it will be centered, not in the upper-left corner.
To test this, I added a framingOffset(_:) function to my ContentView struct:
func framingOffset(_ point: CGPoint?) -> CGPoint {
guard var ret = point else { return CGPoint(x: -1, y: -1) }
guard let arView = coord.arView else { return CGPoint(x: -1, y: -1) }
// Adjust for Circle being "centered on the frame of the view containing it".
// https://developer.apple.com/documentation/swiftui/shape/circle
ret.x -= arView.frame.width / 2.0
ret.y -= arView.frame.height / 2.0
return ret
}
Then changed the circle creation from:
Circle().offset(projectedPosition(of: obj))
To:
Circle().offset(framingOffset(projectedPosition(of: obj)))
With these changes, the marker circle for the the gray sphere placed at the anchor correctly follows its sphere, but when additional spheres are added their marker circles are still a bit off.
So, what else am I missing?
To get a point in 3D world coordinates for use with project(_:), use Entity's convert(position:from:) instance method. The description of convert(position:from:)'s referenceEntity says "Set this to nil to indicate world space.".
In the example above, the code:
// convert position into anchor's space
let modelPos = model.convert(position: model.position, to: anchor)
Should be changed to:
// convert position into world coordinate space
let modelPos = model.convert(position: model.position, to: nil)