gpt4 book ai didi

ios - 带有部分和滑动操作的 SwiftUI 列表一次加载所有行

转载 作者:行者123 更新时间:2023-12-05 08:03:39 27 4
gpt4 key购买 nike

考虑以下代码示例(您可以下载 here ):

struct Item: Identifiable {
var id = UUID()
var name: String
}

struct Row: View {

var item: Item
static var counter = 0

init(item: Item) {
self.item = item

Row.counter += 1
print(Row.counter)
}

var body: some View {
Text(item.name)
}
}

struct ContentView: View {

@State var items = (1...1000).map { Item(name: "Item \($0)") }

var body: some View {
List {
ForEach(items) {
Row(item: $0)
.swipeActions(edge: .leading) {
Button("Action", action: {})
}
}
}
}
}

运行此代码会打印出从 121 的数字,大约是屏幕上可见的行数。

现在,如果我将 ForEach 语句包装在 Section 中,则打印出数字 11000 .因此,没有单元格重用,所有行都被一次加载。

Section {
ForEach(items) {
Row(item: $0)
.swipeActions(edge: .leading) {
Button("Action", action: {})
}
}
}

如果我删除滑动操作,则会打印出数字 118

Section {
ForEach(items) {
Row(item: $0)
}
}

这是已知问题还是我做错了什么?

最佳答案

即使没有滑动操作,我也遇到了这个问题。我使用 .insetGroup 样式为列表创建了一个新的 SectionView,直到 Apple 修复它。缺点是部分页眉和页脚与原始 View 不同。

它已经过测试并适用于 iOS 15 和 16。

struct LazySection<Element, Row: View>: View where Element: Equatable, Element: Identifiable {

// source: https://medium.com/devtechie/round-specific-corners-in-swiftui-d23ceee08188
struct RoundedCorner: Shape {
var radius: CGFloat = .infinity
var corners: UIRectCorner = .allCorners

func path(in rect: CGRect) -> Path {
let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
return Path(path.cgPath)
}
}

let elements: [Element]
var header: String?
var footer: String?
@ViewBuilder let row: (_ element: Element) -> Row

var body: some View {

if let header = header {
HeaderFooter(header, isHeader: true)
.textCase(.uppercase)
}

if let first = elements.first,
let last = elements.last {

if first == last {
row(first)
.listRowBackground(
Rectangle()
.foregroundColor(Color(uiColor: .secondarySystemGroupedBackground))
.clipShape(RoundedCorner(radius: 10))
)
} else {
row(first)
.listRowBackground(
Rectangle()
.foregroundColor(Color(uiColor: .secondarySystemGroupedBackground))
.clipShape(RoundedCorner(radius: 10, corners: [.topLeft, .topRight]))
)
ForEach(elements.dropFirst().dropLast()) { element in
row(element)
}
row(last)
.listRowBackground(
Rectangle()
.foregroundColor(Color(uiColor: .secondarySystemGroupedBackground))
.clipShape(RoundedCorner(radius: 10, corners: [.bottomLeft, .bottomRight]))
)
}
}

if let footer = footer {
HeaderFooter(footer, isHeader: false)
}
}

func HeaderFooter(_ title: String, isHeader: Bool) -> some View {
VStack(alignment: .leading) {
if isHeader == true {
Spacer()
}
Text(title)
.font(.footnote)
if isHeader == false {
Spacer()
}
}
.foregroundColor(.init(uiColor: .secondaryLabel))
.listRowBackground(Color(uiColor: .systemGroupedBackground))
.listRowSeparator(.hidden)
}
}

在给定的代码示例中使用它 Item 必须符合 Equatable。

struct Item: Identifiable, Equatable {
var id = UUID()
var name: String
}

struct Row: View {

var item: Item
static var counter = 0

init(item: Item) {
self.item = item

Row.counter += 1
print(Row.counter)
}

var body: some View {
Text(item.name)
}
}

struct ContentView: View {

@State var items = (1...1000).map { Item(name: "Item \($0)") }

var body: some View {
List {
LazySection(elements: items) { element in
Row(item: element)
}
}
}
}

关于ios - 带有部分和滑动操作的 SwiftUI 列表一次加载所有行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71806868/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com