我在這里重新創建了一個最小的可重復的例子。我使用的是 Xcode 13 beta 5。
在我的專案中,我正在用一個List和ForEach回圈來渲染一個記分卡串列。我正在使用 swipeactions 來實作對記分卡的洗掉。在我洗掉記分卡后,再添加一個記分卡,串列的前緣會呈現額外的填充或listRowInset。
此外,在ContentView中,我使用if/else陳述句在記分卡陣列為空時渲染一條資訊。我認為這就是錯誤發生的地方,但我真的不知道如何解決它。
下面是串列的樣子 ......
而下面是意想不到的、有問題的渲染...
要重現這個錯誤,首先從后緣刷卡洗掉記分卡,然后點擊頂部的添加記分卡,你會看到記分卡的前緣有多余的空白區域。我將附上下面的代碼... 提前感謝您的幫助!
import SwiftUI
struct ContentView。View {
var scorecards = [
Scorecard(date: Date())。
]
var sortedScorecards: [Scorecard] {
get {
scorecards.sorted {
$0.date >/span> $1.date
}
}
set {
記分卡 = newValue
}
}
var body: some View {
VStack {
Button {
scorecards = [
Scorecard(date: Date())。
]
} 標簽。{
Text("Add Scorecard"/span>)
}
if scorecards.count < 1 {
Spacer()
HStack{
Spacer()
Text("沒有以前的記分卡。開始一個記分卡!")
.font(.headline)
.padding(20)
.multilineTextAlignment(.center)
Spacer()
}
Spacer()
} else {
List {
ForEach(sortedScorecards, id:.self) { scorecard in.
if #available(iOS 15.0, *) {
Button {
} 標簽。{
Card(scorecard: scorecard)
}.buttonStyle(.plain)
.listRowInsets(.init(top:7.5,
leading:0,
底部:7.5。
尾部:0)
.swipeActions(edge: .trailing, allowsFullSwipe: false) {
Button("Delete Scorecard"/span>, role: .destructive) {
deleteScorecard(scorecard: scorecard)
}
}
} else {
//Fallback on 早期版本。
}
}
}
.onAppear {
UITableView.appearance().backgroundColor = .black
}
}
}
}
func deleteScorecard(scorecard:Scorecard) {
scorecards = scorecards.filter{$0.id ! = scorecard.id}。
}
}
struct Card: 視圖 {
var scorecard:Scorecard。
func scorecardDate(date:Date) -> String {
let formatter = DateFormatter()
formatter.dateStyle = .short
formatter.timeStyle = .short
return formatter.string(from: date)
}
var body:some View {
ZStack {
Rectangle()
.前景顏色(Color.blue)
.框架(高度:25)。
Text(scorecardDate(date:scorecard.date))
}
}
}
struct Scorecard: Hashable {
func hash(into hasher: inout Hasher) {
hasher.combined(id)
}
var id = UUID().uuidString
var date:Date。
uj5u.com熱心網友回復:
它確實似乎與if/else陳述句有關。當List被從視圖層次中洗掉,然后又被添加進來時,嵌套似乎被搞亂了。
我覺得嵌入的數量很熟悉--就像如果前面有一個洗掉按鈕,它應該被嵌入的數量。因此,根據直覺,我添加了一個明確的呼叫,以將編輯模式設定為.inactive。這似乎是有效的。
在你的視圖的頂部,添加以下內容:
(.editMode) private var editMode
然后,在你的deleteScorecard(scorecard:Scorecard):
func deleteScorecard(scorecard:Scorecard) {
scorecards = scorecards.filter{$0.id ! = scorecard.id}.
editMode?.wrappedValue =.inactive //<-- here.
}
這似乎明確地關閉了編輯模式,然后避免了當List被添加回視圖層次結構時的錯誤。
更新--次要解決方案。
這是我想出的另一個解決方案,因為我的代碼在你的示例代碼中起作用,但在你的應用程式中卻不起作用。在這個版本中,List一直被包含在視圖層次中,但是如果沒有任何專案,框架將被設定為0的高度。由于你所設定的背景顏色,可能會有副作用,這也是我最初沒有包括這個的原因之一,但由于最初的解決方案并不理想,現在值得包括:
var body: some View {
VStack {
Button {
scorecards = [
Scorecard(date: Date())。
]
} 標簽。{
Text("Add Scorecard"/span>)
}
if scorecards.count < 1 {
VStack {
Spacer()
HStack{
Spacer()
Text("沒有以前的記分卡。開始一個記分卡!")
.font(.headline)
.padding(20)
.multilineTextAlignment(.center)
Spacer()
}
Spacer()
}
}
List {
ForEach(sortedScorecards, id:.self) { scorecard in.
if #available(iOS 15.0,*) {
Button {
} 標簽。{
Card(scorecard: scorecard)
}.buttonStyle(.plain)
.listRowInsets(.init(top:7.5,
leading:0,
底部:7.5。
尾部:0)
.swipeActions(edge: .trailing, allowsFullSwipe: false) {
Button("Delete Scorecard"/span>, role: .destructive) {
deleteScorecard(scorecard: scorecard)
}
}
} else {
//Fallback on 早期版本。
}
}
}
.frame(maxHeight: scorecards.count == 0 ? 0 : .infinity)
.onAppear {
UITableView.appearance().backgroundColor = .black
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/323139.html
標籤:
