所以我在運行我的游戲應用程式時收到這個錯誤:
出現更多相同卡片時的游戲螢屏影像(游戲中的所有卡片都應該是唯一的)
ForEach<Range<Int>, Int, ModifiedContent<_ConditionalContent<_ConditionalContent<_ConditionalContent<_ConditionalContent
<ZStack<TupleView<(_ShapeView<Squiggle, ForegroundStyle>,
_StrokedShape<Squiggle>)>>, ZStack<TupleView<(ModifiedContent<_StrokedShape<StripedRect>,
_ClipEffect<Squiggle>>, _StrokedShape<Squiggle>)>>>, _StrokedShape<Squiggle>>,
_ConditionalContent<_ConditionalContent<ZStack<TupleView<(_ShapeView<Capsule, ForegroundStyle>, _StrokedShape<Capsule>)>>,
ZStack<TupleView<(ModifiedContent<_StrokedShape<StripedRect>, _ClipEffect<Capsule>>,
_StrokedShape<Capsule>)>>>, _StrokedShape<Capsule>>>, _ConditionalContent<_ConditionalContent<ZStack<TupleView<(_ShapeView<Diamond,
ForegroundStyle>, _StrokedShape<Diamond>)>>, ZStack<TupleView<(ModifiedContent<_StrokedShape<StripedRect>, _ClipEffect<Diamond>>,
_StrokedShape<Diamond>)>>>, _StrokedShape<Diamond>>>,
_FrameLayout>> count (2) != its initial count (1). `ForEach(_:content:)`
should only be used for *constant* data. Instead conform data to `Identifiable`
or use `ForEach(_:id:content:)` and provide an explicit `id`!
視圖下方的卡片模型似乎并沒有改變。除了卡片上的 numberOfShapes 之外的所有內容都保持不變。因此,顯示錯誤的卡片只有在基礎模型正確匹配時才會匹配,并且不會像視圖中顯示的那樣匹配。
該錯誤似乎僅在我正確設定并按“再顯示三張卡片”或當我顯示的卡片多于可見卡片然后在螢屏上上下滾動時出現。
該應用程式不會因錯誤而停止,但每張卡片上的 numberOfShapes 都會動態變化(如上面的螢屏截圖所示)。(當我滾動到螢屏頂部然后滾動到底部并且某些卡片上的形狀數量每次都會改變時,這是最清楚的)
所以我認為問題可能出在卡片視圖中:
import SwiftUI
struct CardView: View {
var card: Model.Card
var body: some View {
GeometryReader { geometry in
ZStack{
let shape = RoundedRectangle(cornerRadius: 10)
if !card.isMatched {
shape.fill().foregroundColor(.white)
shape.strokeBorder(lineWidth: 4).foregroundColor(card.isSelected ? .red : .blue)
}
VStack {
Spacer(minLength: 0)
//TODO: Error here?
ForEach(0..<card.numberOfShapes.rawValue) { index in
cardShape().frame(height: geometry.size.height/6)
}
Spacer(minLength: 0)
}.padding()
.foregroundColor(setColor())
.aspectRatio(CGFloat(6.0/8.0), contentMode: .fit)
.frame(width: geometry.size.width, height: geometry.size.height)
}
}
}
@ViewBuilder private func cardShape() -> some View {
switch card.shape {
case .squiglle: shapeFill(shape: Squiggle())
case .roundedRectangle: shapeFill(shape: Capsule())
case .diamond: shapeFill(shape: Diamond())
}
}
private func setColor() -> Color {
switch card.color {
case .pink: return Color.pink
case .orange: return Color.orange
case .green: return Color.green
}
}
@ViewBuilder private func shapeFill<setShape>(shape: setShape) -> some View
//TODO: se l?sning, brug rawvalues for cleanness
where setShape: Shape {
switch card.fill {
case .fill: shape.fillAndBorder()
case .stripes: shape.stripe()
case .none: shape.stroke(lineWidth: 2)
}
}
}
卡片視圖顯示在靈活的網格布局中:
import SwiftUI
struct AspectVGrid<Item, ItemView>: View where ItemView: View, Item: Identifiable {
var items: [Item]
var aspectRatio: CGFloat
var content: (Item) -> ItemView
let maxColumnCount = 6
init(items: [Item], aspectRatio: CGFloat, @ViewBuilder content: @escaping (Item) -> ItemView) {
self.items = items
self.aspectRatio = aspectRatio
self.content = content
}
var body: some View {
GeometryReader { geometry in
VStack {
let width: CGFloat = widthThatFits(itemCount: items.count, in: geometry.size, itemAspectRatio: aspectRatio)
ScrollView{
LazyVGrid(columns: [adaptiveGridItem(width: width)], spacing: 0) {
ForEach(items) { item in
content(item).aspectRatio(aspectRatio, contentMode: .fit)
}
Spacer(minLength: 0)
}
}
}
}
}
private func adaptiveGridItem(width: CGFloat) -> GridItem {
var gridItem = GridItem(.adaptive(minimum: width))
gridItem.spacing = 0
return gridItem
}
看法:
import SwiftUI
struct SetGameView: View {
@StateObject var game: ViewModel
var body: some View {
VStack{
HStack(alignment: .bottom){
Text("Set Game")
.font(.largeTitle)
}
AspectVGrid(items: game.cards, aspectRatio: 2/3) { card in
CardView(card: card)
.padding(4)
.onTapGesture {
game.choose(card)
}
}.foregroundColor(.blue)
.padding(.horizontal)
Button("show 3 more cards"){
game.showThreeMoreCardsFromDeck()
}
}
}
}
非常感謝任何幫助解決這個問題。我已經花了很多時間在這上面。
uj5u.com熱心網友回復:
你的問題在這里:
ForEach(0..<card.numberOfShapes.rawValue) { index in cardShape().frame(height: geometry.size.height/6) }
這個ForEach初始值設定項的第一個引數是 a Range<Int>。檔案說(強調):
實體只讀取提供資料的初始值,不需要跨更新識別視圖。要在動態范圍內按需計算視圖,請使用
ForEach/init(_:id:content:)。
因為它只讀取“所提供資料的初始值”,所以只有當Range<Int>是常量時才可以安全使用。如果改變范圍,效果是不可預測的。因此,從 Xcode 13 開始,如果您傳遞非常量范圍,編譯器會發出警告。
現在,也許您的范圍 ( 0..<card.numberOfShapes.rawValue) 確實是恒定的。但是編譯器不知道。(并且根據您的錯誤,它不是一個恒定的范圍。)
您可以通過切換到帶id:引數的初始化程式來避免警告:
ForEach(0..<card.numberOfShapes.rawValue, id: \.self) { index in
// ^^^^^^^^^^^^^
// add this
cardShape().frame(height: geometry.size.height/6)
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/354926.html
上一篇:使用Javascript或jQuery從文本框輸入創建陣列,并可以在單擊時洗掉陣列元素
下一篇:控制器無法系結屬性
