我正在尝试创建分页滚动视图 我使用 TabView 来创建它。
这是我的代码
struct TT: Identifiable {
let id = UUID()
var v: String
}
struct TTest: View {
@State var currentIndex = 0
@State var data = [
TT(v: "0")
]
var body: some View {
VStack {
SwiftUI.TabView(selection: $currentIndex) {
ForEach(data.indexed(), id: \.1.id) { index, value in
TTestConsomer(data: $data[index]).tag(index)
}
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
Spacer()
HStack {
Image(systemName: "plus")
.resizable()
.frame(width: 50, height: 50)
.onTapGesture(perform: add)
Image(systemName: "minus")
.resizable()
.frame(width: 50, height: 5)
.onTapGesture(perform: delete)
}
Text("\(currentIndex + 1)/\(data.count)")
}
}
func add() {
data.append(TT(v: "\(data.count)") )
}
func delete() {
data.remove(at: currentIndex)
}
}
struct TTestConsomer: View {
@Binding var data: TT
var body: some View {
Text(data.v)
.padding(30)
.border(Color.black)
}
}
// You also need this extension
extension RandomAccessCollection {
func indexed() -> IndexedCollection<Self> {
IndexedCollection(base: self)
}
}
struct IndexedCollection<Base: RandomAccessCollection>: RandomAccessCollection {
typealias Index = Base.Index
typealias Element = (index: Index, element: Base.Element)
let base: Base
var startIndex: Index { base.startIndex }
var endIndex: Index { base.endIndex }
func index(after i: Index) -> Index {
base.index(after: i)
}
func index(before i: Index) -> Index {
base.index(before: i)
}
func index(_ i: Index, offsetBy distance: Int) -> Index {
base.index(i, offsetBy: distance)
}
subscript(position: Index) -> Element {
(index: position, element: base[position])
}
}
当我点击 + 按钮时,我可以添加更多标签。 但是当我点击删除按钮时,我的应用程序崩溃了。 这里有什么问题?代码似乎没有任何问题。
答案 0 :(得分:1)
不,我不认为你做错了什么。几个月前,我向 Apple 提交了一个关于 TabView 相关问题的问题,但从未收到任何回复。调试来自集合视图协调器:
#0 0x00007fff57011ca4 in Coordinator.collectionView(_:cellForItemAt:) ()
似乎在删除项目后,底层集合视图没有更新。在 UIKit 中,我们可能会调用 .reloadData() 来强制它更新。在 SwiftUI 中,您可以在屏幕上重绘集合视图以强制其更新。显然,这会影响 UI,并不是一个完美的解决方案。
struct TabViewTest: View {
@State var isLoading: Bool = false
@State var data: [String] = [
"one",
"two"
]
var body: some View {
if !isLoading, !data.isEmpty {
TabView {
ForEach(data, id: \.self) { item in
Text(item)
.tabItem { Text(item) }
}
}
.tabViewStyle(PageTabViewStyle())
.overlay(
HStack {
Text("Add")
.onTapGesture {
add()
}
Text("remove")
.onTapGesture {
remove()
}
}
, alignment: .bottom
)
}
}
func add() {
data.append("three")
print(data)
}
func remove() {
isLoading = true
data.removeFirst()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
isLoading = false
}
print(data)
}
}
struct TabVIewTest_Previews: PreviewProvider {
static var previews: some View {
TabViewTest()
}
}