I'm trying to make a bidirectional TabView (with .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
) whose datasource will change over time.
Below is the code that describes what is expected in the result:
class TabsViewModel: ObservableObject {
@Published var items = [-2, -1, 0, 1, 2]
@Published var selectedItem = 2 {
didSet {
if let index = items.firstIndex(of: selectedItem), index >= items.count - 2 {
items = items + [items.last! + 1]
items.removeFirst()
}
if let index = items.firstIndex(of: selectedItem), index <= 1 {
items = [items.first! - 1] + items
items.removeLast()
}
}
}
}
struct TabsView: View {
@StateObject var vm = TabsViewModel()
var body: some View {
TabView(selection: $vm.selectedItem) {
ForEach(vm.items, id: \.self) { item in
Text(item.description)
.frame(minWidth: 0,
maxWidth: .infinity,
minHeight: 0,
maxHeight: .infinity,
alignment: .topLeading
)
.background(Color(hue: .random(in: 0...0.99), saturation: .random(in: 0...0.99), brightness: 0.5))
}
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
}
}
In this case, when you try to go to next or previous page, the animation breaks off and the original page instantly returns to its place.
Is it possible to implement this exactly with TabView, without help of UIKit and third-party frameworks?
My guess is one of the possible solutions is to change the data source when the transition animation finishes, but I couldn't find a way to do this in SwiftUI.
Is my guess correct? Perhaps there are other more elegant ways to implement this functionality, and I'm coming from the wrong side.