如何在页面滚动视图(TabView)中添加/删除视图



我正在尝试创建一个分页滚动视图我使用了一个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])
}
}

当我点击+按钮时,我可以添加更多的选项卡。但当我点击删除按钮时,我的应用程序就会崩溃。这里有什么问题?代码似乎没有任何问题。

不,我不认为你做错了什么。几个月前,我在TabView上向苹果提交了一个关于相关问题的问题,但从未收到任何回复。调试来自集合视图协调器:
#0  0x00007fff57011ca4 in Coordinator.collectionView(_:cellForItemAt:) ()

删除项目后,基础集合视图似乎不会更新。在UIKit中,我们可能会调用.reloadData((来强制它更新。在SwiftUI中,您可以在屏幕上重新绘制集合视图,以强制其更新。显然,这会影响用户界面,并不是一个完美的解决方案。

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()
}
}

最新更新