如何从分页 ScrollView (TabView) 添加/删除视图

时间:2021-01-11 01:32:24

标签: swiftui

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

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

1 个答案:

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