このcircles
配列を使用すると、円がランダムな位置に作成され、フェードアウトします。円がフェードアウトしたら、それを完全に削除する必要があります。これは、フェードアウトアニメーションの終了に等しい遅延の後に、配列内の対応する行を削除することによって実現されます。
「サークルを追加」ボタンをクリックする頻度が削除速度よりも少ない限り、問題なく動作します。ただし、速く押し続けると、ビューがindex out of range
。でクラッシュします。これは、アルゴリズムが混乱した結果であるように見えます。インデックスによって削除される行を識別しますが、その間に他の行が削除/追加された可能性があります。つまり、インデックスはすでに異なっています。
参照してください:
import SwiftUI
let screenW = UIScreen.main.bounds.size.width
let screenH = UIScreen.main.bounds.size.height
struct PlayGround: View {
struct BlackCircle {
var id = UUID()
var position: CGPoint
var opacity: Double = 1
}
@State var circles: [BlackCircle] = []
var body: some View {
ZStack {
ForEach(Array(circles.enumerated()), id: \.1.id) {
index, item in
Circle()
.frame(width:30, height:30)
.position(item.position)
.opacity(item.opacity)
.onAppear {
let animation = Animation.linear(duration: 1)
withAnimation(animation) {
circles[index].opacity = 0
}
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
circles.remove(at: index)
}
}
}.frame(width: screenW, height:screenH)
Button(action: {
let randx = CGFloat.random(in: 30...screenW-30)
let randy = CGFloat.random(in: 30...screenH-30)
let randpos = CGPoint(x: randx, y: randy)
circles.append(BlackCircle(position: randpos))
}, label: {
Text("Add a Circle")
})
}
}
}
これを解決する最も簡単で手間のかからない方法は、円がフェードアウトしたときに行を削除しないことです。ただし、これは確かにエレガントではなく非効率的です(配列に何千もの役に立たない行が含まれる可能性があります)。では、新しい要素が常に追加および遅延削除されているときに配列がクラッシュするのを防ぐにはどうすればよいですか?
ありがとう!
インデックスが範囲外であることが原因で問題が発生している場合は、インデックスではなくidに基づいて円を削除してみてください。
circles.removeAll { (existingCircle) -> Bool in
return existingCircle.id == item.id
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加