SwiftUI 中的双向无限 PageView
Posted
技术标签:
【中文标题】SwiftUI 中的双向无限 PageView【英文标题】:Bidirectional infinite PageView in SwiftUI 【发布时间】:2020-12-26 14:56:28 【问题描述】:我正在尝试制作一个双向 TabView(使用 .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
),其数据源会随着时间而改变。
下面是描述预期结果的代码:
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))
在这种情况下,当您尝试转到下一页或上一页时,动画会中断,原始页面会立即返回原位。
是否可以在不借助 UIKit 和第三方框架的情况下使用 TabView 完全实现这一点?
我的猜测是可能的解决方案之一是在过渡动画完成时更改数据源,但我在 SwiftUI 中找不到这样做的方法。 我的猜测正确吗?也许还有其他更优雅的方式来实现这个功能,而我的想法是错误的。
【问题讨论】:
SwiftUI 由很多开箱即用的View
s 组成,如果你想自定义它,最好使用相同View
的UIKit 形式之一。 Apple 有 SwiftUI 教程,它们会指导您如何制作与您正在寻找的东西相似的东西。 developer.apple.com/tutorials/swiftui/interfacing-with-uikit
这可能对你有帮助:How can I implement PageView in SwiftUI?
lorem ipsum,pawelio2222,感谢您的 cmets。我已经尝试从这个链接实现示例(我失败了,稍后再试)。最后我设法用 SwiftUIPager 框架实现了它。现在我想知道是否可以使用“纯”TabView 来实现所描述的任务。
【参考方案1】:
任务本身可以使用SwiftUIPager 框架来解决。
import SwiftUI
import SwiftUIPager
class PagerConteinerViewModel: ObservableObject
@Published var items = [-3, -2, -1, 0, 1, 2, 3]
@Published var selectedItemIndex = 3
func updateItems (_ direction: Double)
withAnimation
if direction > 0 && selectedItemIndex >= items.count - 3
items = items + [items.last! + 1]
items.removeFirst()
if direction < 0 && selectedItemIndex <= 2
items = [items.first! - 1] + items
items.removeLast()
struct PagerContainerView: View
@StateObject var vm = PagerConteinerViewModel()
var body: some View
Pager(page: $vm.selectedItemIndex, data: vm.items, id: \.self) item in
Text("\(item)")
.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))
.onDraggingEnded(vm.updateItems)
文档usesonPageChanged
更新数据源,但随后在数组的中间或开头插入值会使应用程序崩溃。
【讨论】:
以上是关于SwiftUI 中的双向无限 PageView的主要内容,如果未能解决你的问题,请参考以下文章