【问题标题】:SwiftUI: stuck on infinite page view implementationSwiftUI:卡在无限页面视图实现上
【发布时间】:2021-04-02 22:45:22
【问题描述】:

我正在尝试在纯 SwiftUI 中创建一个 PageView。下面是我的测试代码。一切都按预期工作,但 DragGesture 除外。它只是不调用“onEnded”函数。绝不。我该如何解决?

struct PageView<V: View>: Identifiable {
    let id = UUID()
    var content: V
}

struct InfinitePageView: View {
    @State private var pages: [PageView] = [
        PageView(content: Text("Page")),
        PageView(content: Text("Page")),
        PageView(content: Text("Page"))
    ]
    
    @State private var selectedIndex: Int = 1
    @State private var isDragging: Bool = false
    
    private var drag: some Gesture {
        DragGesture()
            .onChanged { _ in
                self.isDragging = true
            }
            .onEnded { _ in
                self.isDragging = false
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                    resolvePages()
                }
            }
    }
    
    var body: some View {
        NavigationView {
            TabView(selection: $selectedIndex) {
                ForEach(pages) { page in
                    page.content
                        .tag(pages.firstIndex(where: { $0.id == page.id })!)
                }
            }
            .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
            .gesture(drag)
            .onChange(of: selectedIndex, perform: { value in
                guard !isDragging else { return }
                DispatchQueue.main.async {
                    resolvePages()
                }
            })
        }
    }
    
    private func resolvePages() {
        if selectedIndex > 1 {
            addNextPage()
        }
        if selectedIndex < 1 {
            addPreviousPage()
        }
    }
    
    private func addNextPage() {
        pages.append(PageView(content: Text("Page")))
        pages.removeFirst()
        selectedIndex = 1
    }
    
    private func addPreviousPage() {
        pages.insert(PageView(content: Text("Page")), at: 0)
        pages.removeLast()
        selectedIndex = 1
    }
}

【问题讨论】:

  • 我没有您的问题的答案,但我试图做类似的事情并最终在此视频中使用了无限轮播 (youtube.com/watch?v=fB5MzDD1PZI&feature=emb_title)。他在描述中包含了一个指向源代码的链接,它是纯 SwiftUI(使用 ZStack/Offset/Animation)。您可能可以很容易地更新代码以使其成为全屏寻呼机。

标签: ios swiftui uikit uipageviewcontroller infinite-scroll


【解决方案1】:

这是 SwiftUI 的一个已知问题

您设置的DragGesture 可能会被TabView 中的DragGesture 覆盖。

可以使用本文Detect DragGesture cancelation in SwiftUI 中的设置检测onEnded,但这会停用TabView/Page 手势。

您的 selectedIndex 代码在选择新页面后运行,其行为应与 onEnded 相同。

【讨论】:

  • 问题是,如果我在连续拖动的同时更改页面数组状态变量,那么 TabView 会立即重新加载,而不会滚动到页面动画。
  • 好点可能是覆盖您的DragGesture 的手势。由于 SwiftUI 的固有特性(自动化程度如此之高),因此需要权衡取舍。 Apple 有 SwiftUI 教程,其中一个有一个“手动” PageView,你可能会得到更大的灵活性。 developer.apple.com/tutorials/swiftui/interfacing-with-uikit 但如果您需要更多,您可能必须创建自己的(不使用 TabView 的功能)
  • 是的,我想除了使用 UIKit 的 UPageViewController 包装器之外别无他法。刚刚尝试用纯 SwiftUI 完成任务。
  • 看起来,带有 PageTabViewStyle 的 TabView 使用了一些名为 _UIPageSheetPresentationController 的私有类。使用 Introspect 框架甚至无法获得任何结果:(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-16
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
相关资源
最近更新 更多