Hi,
I am using matched geometry effect to animate small image views as the row expands when the user taps on it. I am getting the error AttributeGraph precondition failure: invalid value type for attribute: 3580720 (saw ViewTransform, expected Phase).
The error occurs randomly, either when switching into and out of different ItemsView
s or when expanding different rows. The error is highlighted in the <AppName>App.swift
file at the @main
line at the top.
Here's the code. Please do help me I've been frustrated at this issue. I've seen similar issues on forums but none of the solutions have worked. I believe the issue is due to the matchedGeometryEffect itself, as if I remove those lines, the app doesn't crash.
// ItemsView.swift
...
var body: some View {
ScrollView {
VStack(alignment: .leading) {
...
ItemsView
}
}
}
@ViewBuilder
var ItemsView: some View {
ForEach(items) { item in
ItemRow(item: item)
}
}
// ItemRow.swift
@Namespace private var animation
@State private var isShowingDetails = false
var body: some View {
HStack {
...
ZStack(alignment: .trailing) {
...
ItemDetailsView
}
}
@ViewBuilder
var ItemDetailsView: some View {
if showingItemDetails {
ExpandedDetailView
} else {
CompactDetailView
}
}
var CompactDetailView: some View {
HStack(alignment: .center) {
if item.isFlagged {
Image(systemName: "flag.circle.fill")
.matchedGeometryEffect(id: "flag", in: animation)
.foregroundColor(.orange)
}
if !item.wrappedTags.isEmpty {
ForEach(item.wrappedTags) { itemTag in
Image(systemName: "tag.circle")
.foregroundColor(itemTag.wrappedColor)
.matchedGeometryEffect(id: "\(itemTag.objectID)", in: animation)
}
}
if item.reminder != nil {
Image(systemName: reminderIcon)
.matchedGeometryEffect(id: "reminder", in: animation)
.foregroundColor(item.isOverdue && item.wrappedReminderRepeatType == .none ? .red : .accentColor)
}
if item.wrappedNotes != "" {
Image(systemName: "note.text")
.matchedGeometryEffect(id: "notes", in: animation)
}
if !item.wrappedSubItems.isEmpty {
Image(systemName: "list.bullet")
.matchedGeometryEffect(id: "subItems", in: animation)
}
}
.foregroundColor(itemRowColor)
.imageScale(.medium)
}
var ExpandedDetailView: some View {
VStack(alignment: .leading, spacing: 5) {
if item.isFlagged {
HStack(alignment: .center) {
Image(systemName: "flag.circle.fill")
.matchedGeometryEffect(id: "flag", in: animation)
Text("Flagged".uppercased())
}
.foregroundColor(.orange)
}
ForEach(item.wrappedTags) { itemTag in
HStack(alignment: .center) {
Image(systemName: "tag.circle")
.foregroundColor(itemTag.wrappedColor)
.matchedGeometryEffect(id: "\(itemTag.objectID)", in: animation)
Text(itemTag.wrappedName.uppercased())
.fontWeight(.light)
}
.foregroundColor(itemTag.wrappedColor)
}
if item.reminder != nil {
HStack(alignment: .center) {
Image(systemName: reminderIcon)
.matchedGeometryEffect(id: "reminder", in: animation)
VStack(alignment: .leading) {
if item.wrappedReminderRepeatType != .none {
Text(item.wrappedReminderRepeatType.rawValue)
}
Text(item.reminder!, formatter: dateFormatter)
}
}
.foregroundColor(item.isOverdue && item.wrappedReminderRepeatType == .none ? .red : .accentColor)
}
if item.wrappedNotes != "" {
HStack(alignment: .center) {
Image(systemName: "note.text")
.matchedGeometryEffect(id: "notes", in: animation)
Text(item.wrappedNotes)
.fontWeight(.light)
.minimumScaleFactor(1.0)
.lineLimit(2)
.truncationMode(.tail)
}
}
if !item.wrappedSubItems.isEmpty {
HStack(alignment: .center) {
Image(systemName: "list.bullet")
.matchedGeometryEffect(id: "subItems", in: animation)
VStack(alignment: .leading) {
ForEach(item.wrappedSubItems) { subItem in
HStack(alignment: .center) {
Image(systemName: subItem.isCompleted ? "checkmark.circle.fill" : "circle")
.imageScale(.small)
Text(subItem.name)
}
}
}
}
}
}
.foregroundColor(itemRowColor)
.imageScale(.medium)
.padding(.top, 1)
}