Swiftui listRowInsets在添加到空数组时做出意想不到的更改



我在这里重新创建了一个最小的可复制示例。我使用的是Xcode 13 beta 5.

在我的项目中,我正在呈现一个带有List和ForEach循环的记分卡列表。我正在使用swipeactions来删除记分卡。在我删除记分卡之后,然后添加一个记分卡,这个列表在边缘被渲染为额外的填充或listRowInset。

同样,在ContentView中,当记分卡数组为空时,我使用if/else语句来呈现消息。我想这就是bug发生的地方,但我真的不知道如何解决它。

列表应该是这样的…

列表的正确呈现

和下面是意想不到的,有bug的渲染…

删除记分卡并添加新记分卡后呈现不正确

要重新创建该bug,首先通过从后缘滑动删除记分卡,然后单击顶部的添加记分卡,您将看到记分卡前沿的额外空白。我将附上下面的代码…提前感谢您的帮助!

import SwiftUI
struct ContentView: View {
@State var scorecards = [
Scorecard(date: Date()),

]
var sortedScorecards: [Scorecard] {
get {
scorecards.sorted {
$0.date > $1.date
}
}
set {
scorecards = newValue
}
}
var body: some View {
VStack {

Button {
scorecards = [
Scorecard(date: Date()),

]

} label: {
Text("Add Scorecard")
}


if scorecards.count < 1 {

Spacer()

HStack{
Spacer()
Text("No previous scorecards. Start a scorecard!")
.font(.headline)
.padding(20)
.multilineTextAlignment(.center)
Spacer()
}
Spacer()
} else {
List {
ForEach(sortedScorecards, id:.self) { scorecard in
if #available(iOS 15.0, *) {

Button {

} label: {
Card(scorecard: scorecard)

}.buttonStyle(.plain)
.listRowInsets(.init(top:7.5,
leading:0,
bottom:7.5,
trailing:0))
.swipeActions(edge: .trailing, allowsFullSwipe: false) {
Button("Delete Scorecard", role: .destructive) {
deleteScorecard(scorecard: scorecard)
}
}


} else {
// Fallback on earlier versions
}
}
}
.onAppear {
UITableView.appearance().backgroundColor = .black
}
}
}

}
func deleteScorecard(scorecard:Scorecard) {
scorecards = scorecards.filter{$0.id != scorecard.id}
}
}

struct Card: View {

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()
.foregroundColor(Color.blue)
.frame(height: 25)

Text(scorecardDate(date:scorecard.date))

}
}
}


struct Scorecard:Hashable {
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}

var id = UUID().uuidString
var date:Date
}

似乎与if/else语句有关。当List从视图层次结构中删除然后添加回来时,insert似乎变得混乱。

插入的数量对我来说很熟悉——就像如果在前面有一个删除按钮应该插入的数量一样。所以,根据直觉,我添加了一个显式调用,将编辑模式设置为.inactive。这似乎行得通。

在视图的顶部添加:

@Environment(.editMode) private var editMode

然后,在您的deleteScorecard(scorecard:Scorecard)中:

func deleteScorecard(scorecard:Scorecard) {
scorecards = scorecards.filter{$0.id != scorecard.id}
editMode?.wrappedValue = .inactive //<-- here
}

这似乎明确地关闭了编辑模式,然后避免了当List被添加回视图层次结构时的错误。


Update - secondary solution.

这是我想出的另一个解决方案,因为我的代码与你的示例代码工作,但不是与你的应用程序。在这个版本中,List被包含在整个视图层次结构中,但框架被设置为0的高度,如果没有任何项目。由于你所设置的背景颜色,可能会有副作用,这也是我最初没有包括这个的原因之一,但由于最初的解决方案并不理想,现在值得包括:

var body: some View {
VStack {

Button {
scorecards = [
Scorecard(date: Date()),

]

} label: {
Text("Add Scorecard")
}


if scorecards.count < 1 {

VStack {
Spacer()

HStack{
Spacer()
Text("No previous scorecards. Start a scorecard!")
.font(.headline)
.padding(20)
.multilineTextAlignment(.center)
Spacer()
}
Spacer()
}

}

List {
ForEach(sortedScorecards, id:.self) { scorecard in
if #available(iOS 15.0, *) {

Button {

} label: {
Card(scorecard: scorecard)

}.buttonStyle(.plain)
.listRowInsets(.init(top:7.5,
leading:0,
bottom:7.5,
trailing:0))
.swipeActions(edge: .trailing, allowsFullSwipe: false) {
Button("Delete Scorecard", role: .destructive) {
deleteScorecard(scorecard: scorecard)
}
}


} else {
// Fallback on earlier versions
}
}
}
.frame(maxHeight: scorecards.count == 0 ? 0 : .infinity)
.onAppear {
UITableView.appearance().backgroundColor = .black
}
}

}

相关内容

  • 没有找到相关文章

最新更新