SwiftUI:删除 ForEach 中的最后一行
Posted
技术标签:
【中文标题】SwiftUI:删除 ForEach 中的最后一行【英文标题】:SwiftUI: Deleting last row in ForEach 【发布时间】:2020-04-25 23:54:31 【问题描述】:我正在尝试删除 ForEach
中的行。删除最后一行总是会引发索引超出范围异常。删除任何其他行不会。
ForEach(Array(player.scores.enumerated()), id: \.element) index, score in
HStack
if self.isEditSelected
Button(action:
self.player.scores.remove(at: index)
, label:
Image("delete")
)
TextField("\(score)", value: self.$player.scores[index], formatter: NumberFormatter())
我尝试过使用ForEach(player.indices...)
和ForEach(player.scores...)
,但遇到了同样的问题。
在我看来,崩溃发生在这里self.$player.scores[index]
,因为将索引硬编码为除最后一行工作之外的任何值。
有谁知道如何解决这个问题?或者如果有更好的方法。
【问题讨论】:
这能回答你的问题吗? Deletable Table with TextField on SwiftUI 【参考方案1】:这里是修复
ForEach(Array(player.scores.enumerated()), id: \.element) index, score in
HStack
if self.isEditSelected
Button(action:
self.player.scores.remove(at: index)
, label:
Image("delete")
)
TextField("\(score)", value: Binding( // << use proxy binding !!
get: self.player.scores[index] ,
set: self.player.scores[index] = $0 ),
formatter: NumberFormatter())
【讨论】:
太棒了。这是在具有非恒定范围的情况下枚举 Array 的最佳方式! 你知道@Asperi 为什么代理绑定会阻止视图在索引更新之前尝试重绘吗?它是一种 hack 还是一种合法的编码方式? @Asperi 为什么它解决了这个问题?出了什么问题……为什么现在是正确的?【参考方案2】:基于@Asperi 的回答
public extension Binding where Value: Equatable
static func proxy(_ source: Binding<Value>) -> Binding<Value>
self.init(
get: source.wrappedValue ,
set: source.wrappedValue = $0
)
你可以这样使用:
TextField("Name", text: .proxy($variable))
【讨论】:
【参考方案3】:Xcode 13.0 beta 引入了一种在集合元素和 ForEach / List 构建的视图之间建立双向绑定的新方法。 此方法修复了与删除最后一行相关的崩溃问题。
struct Score: Identifiable
let id = UUID()
var value: Int
struct Player
var scores: [Score] = (1...10).map _ in .init(value: Int.random(in: 0...25))
struct BindingTest: View
@State private var player = Player()
var body: some View
List
ForEach($player.scores) $score in
HStack
TextField("\(score.value)", value: $score.value,
formatter: NumberFormatter())
.onDelete player.scores.remove(atOffsets: $0)
【讨论】:
以上是关于SwiftUI:删除 ForEach 中的最后一行的主要内容,如果未能解决你的问题,请参考以下文章
删除最后一个数组元素时,SwiftUI列表ForEach索引超出范围
如何着色/删除 SwiftUI 列表中最后一行和倒数第二行之间的分隔符?
SwiftUI 中 ForEach 结构的最后一个参数的函数类型是啥?
SwiftUI NavigationView 与 List 内 ForEach 中的 NavigationLink 来回跳转