SwiftUI-LazyVGrid单元上的contextMenu在存在地图时导致动画崩溃

问题描述

我有一个LazyVGrid和一个NavigationBarItem按钮,用于更改列数。它在1、2、3之间循环,然后又回到1,依此类推。我使用.animation(.default)修饰符来动画化此更改。当只有一列时,我使用了一个包含小的Map元素的不同单元格结构。我有一个contextMenu可以很好地用于2列和3列,但是在单列单元格上使用时会立即崩溃。

AnimationError [2652:855376] [未知进程名称] CGImageCreate:无效的图像alphaInfo:kCGImageAlphaNone。应该是kCGImageAlphaNoneSkipLast

此崩溃仅发生在我的iPhone 11 Pro真实设备上,模拟器可以很好地处理它。如果我删除动画,那一切都很好。

可精简的可编译版本:

import SwiftUI
import CoreLocation
import MapKit

struct HillMO: Identifiable {
    let id = UUID()
    let name: String
    let latitude: Double
    let longitude: Double
}

struct ContentView: View {
    
    @State private var gridLayout: [GridItem] = [GridItem(),GridItem(),GridItem()]
    
    var body: some View {
        NavigationView {
            VStack {
                GeometryReader { geometry in
                    ScrollView {
                        LazyVGrid(columns: gridLayout,alignment: .center,spacing: 8) {
                            ForEach(hills) { hill in
                                Cell(hill: hill,width: geometry.size.width,columns: gridLayout.count)
                                    .contextMenu {
                                        Button(action: { }) { Label("Bingo",image: "eyeglasses") }
                                        Button(action: { }) { Label("Bungo",image: "hourglass") }
                                    }
                            }
                        }.padding(5)
                        .animation(.default)
                    }
                }
            }
            .navigationBarTitle("Bagger")
            .navigationBarItems(
                trailing: HStack {
                    Button(action: {
                        gridLayout = Array(repeating: .init(.flexible()),count: gridLayout.count % 3 + 1)
                    }) {
                        Image(systemName: "circle.grid.3x3")
                    }
                }
            )
        }
    }
    
    let hills = [ HillMO(name: "un",latitude: 0.0,longitude: 0.0),HillMO(name: "dau",latitude: 1.0,longitude: 1.0),HillMO(name: "tri",latitude: 2.0,longitude: 2.0),HillMO(name: "pedwar",latitude: 3.0,longitude: 3.0),HillMO(name: "pump",latitude: 4.0,longitude: 4.0),HillMO(name: "chwech",latitude: 5.0,longitude: 5.0)
                ]
}

我的单元格和CellMap视图:

struct Cell: View {
    
    var hill: HillMO
    var width: CGFloat
    var columns: Int
    
    var body: some View {
        Group {
            if columns != 1 {
                ZStack {
                    Rectangle()
                    Text(hill.name).foregroundColor(.white)
                }
            } else {
                ZStack {
                    Rectangle()
                    HStack {
                        Text(hill.name).foregroundColor(.white)
                        Spacer()
                        CellMap(coordinateRegion: MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: hill.latitude,longitude: hill.longitude),latitudinalMeters: 300000,longitudinalMeters: 300000))
                            .frame(width: (width / CGFloat(columns)) * 0.24,height: (width / CGFloat(columns)) * 0.24)
                            .clipShape(Circle())
                    }
                }
            }
        }
        .frame(height: (width / CGFloat(columns)) * (columns == 1 ? 0.25 : 1.25))
    }
}

struct CellMap: View {
    
    @State var coordinateRegion: MKCoordinateRegion
    
    var body: some View {
        Map(coordinateRegion: $coordinateRegion)
    }
}

解决方法

尝试将动画仅限制为精确的状态值

}.padding(5)
.animation(.default,value: gridLayout)

这将要求使HillMO相等

struct HillMO: Identifiable,Equatable {
    static func == (lhs: Self,rhs: Self) -> Bool {
        lhs.id == rhs.id
    }

    let id = UUID()
    let name: String
    let latitude: Double
    let longitude: Double
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...