SwiftUI - LazyVGrid 单元格上的上下文菜单在地图存在时导致动画崩溃
SwiftUI - contextMenu on LazyVGrid cell causing animation crash when Map present
我有一个 LazyVGrid 和一个更改列数的 NavigationBarItem 按钮。它循环通过 1、2、3,然后回到 1,等等。我使用 .animation(.default)
修饰符来为这个变化设置动画。当只有一列时,我使用包含一个小地图元素的不同单元格结构。我有一个上下文菜单,它适用于 2 列和 3 列,但在单列单元格上使用时会立即崩溃。
AnimationError[2652:855376] [Unknown process name] CGImageCreate: invalid image alphaInfo: kCGImageAlphaNone. It should be 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)
]
}
我的 Cell 和 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
}
我有一个 LazyVGrid 和一个更改列数的 NavigationBarItem 按钮。它循环通过 1、2、3,然后回到 1,等等。我使用 .animation(.default)
修饰符来为这个变化设置动画。当只有一列时,我使用包含一个小地图元素的不同单元格结构。我有一个上下文菜单,它适用于 2 列和 3 列,但在单列单元格上使用时会立即崩溃。
AnimationError[2652:855376] [Unknown process name] CGImageCreate: invalid image alphaInfo: kCGImageAlphaNone. It should be 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)
]
}
我的 Cell 和 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
}