SwiftUI:如何在用户滑动时实现分页? (之前使用的 UICollectionView -> 启用分页)

Posted

技术标签:

【中文标题】SwiftUI:如何在用户滑动时实现分页? (之前使用的 UICollectionView -> 启用分页)【英文标题】:SwiftUI: How to implement paging on user swipe? (Previously used UICollectionView -> paging enabled) 【发布时间】:2020-08-10 22:27:47 【问题描述】:

背景:我正在将一个项目从 UIKit 转换为 SwiftUI。目前使用 UIKit,我在 UICollectionView 中有一个 UICollectionView,两者都启用了分页。这允许用户在单元格上向上/向下和向左/向右滑动。每个单元格填满整个屏幕(类似于 TikTok 的主 UI),每个单元格都有很多数据要从 Firebase 中提取,所以我不想在第一个视图出现时加载所有项目,而是在每个单元格出现时加载(这个是通过 UICollectionView 委托在 UIKit 下的当前实现)。

问题:我找不到在 SwiftUI 中启用这种“分页”(基于用户滑动)的方法。很难想象 Apple 在没有 Paging 功能的情况下制作了这个新框架?如果他们没有包括这个,有没有解决方法?否则,有没有一种简单的方法可以将 UICollectionView 包含到 SwiftUIView 中?

任何帮助或解决方法都会很好!谢谢:)

【问题讨论】:

转换的原因是什么? 【参考方案1】:

SwiftUI 2

看起来LazyGrid 可能是您需要的。

这是一个垂直网格的示例代码:

struct ContentView: View 
    let data = (1...1000).map  "Item \($0)" 

    let columns = [
        GridItem(.adaptive(minimum: 80))
    ]

    var body: some View 
        ScrollView 
            LazyVGrid(columns: columns, spacing: 20) 
                ForEach(data, id: \.self)  item in
                    Text(item)
                
            
            .padding(.horizontal)
        
    

您可以在这些链接中找到更多信息:

SwiftUI Lazy Grid Tutorial Impossible Grids with SwiftUI How to position views in a grid using LazyVGrid and LazyHGrid

SwiftUI 1

如果您绑定到 ios 13 或 LazyGrid 只是不符合您的期望,您仍然可以将您的 UICollectionView 包装在 UIViewRepresentable 中。

更多解释见此链接:Implementing UICollectionView / UICollectionView DiffableDataSource in SwiftUI

【讨论】:

谢谢!!我将在本周晚些时候尝试实施这一点。我正在运行 Xcode 11.6(没有 LazyGrid),但我刚刚下载了 Xcode 12.0 测试版并立即查看!但是,据我了解,当 Xcode 处于测试阶段时,我们实际上无法从 Xcode 部署构建。你知道我们什么时候期望 Xcode 12.0 可以用来将一个版本推送到 App Store 吗?我对此很陌生,只是想谨慎构建 Beta 版本并不得不等待数月才能将其部署到 App Store? @purebreadd 目前还没有官方消息,可能在秋天。请注意,SwiftUI 2.0 在 iOS14+ 上可用,SwiftUI 1.0 在 iOS13+ 上可用。最好在 在 SwiftUI 中重写您的应用程序之前了解这一点。 您好,我现在正在使用 GridItems,并且已经将惰性单元格放置到位。但是,ScrollViews 只是平滑滚动而不是分页。知道如何在它们上启用“分页”吗? UICollectionView 曾经有一个不错的小委托 :( @purebreadd 您可以使用 UIViewRepresentable 将 UIKit 集成到 SwiftUI 中。见Implementing UICollectionView / UICollectionView DiffableDataSource in SwiftUI。我也更新了我的答案。 如果你很好奇,我经历了将 UICollectionView 转换为 SwiftUI 并将所有自定义大小/单元格合并到我们的应用程序中的过程,这变得很头疼。这种方法可能最适合简单的 UICollectionViews。无论如何,我们现在的解决方案是使用旧项目(将功能保留在具有复杂 CollecionView 的屏幕上)并且仅将不需要此功能的屏幕更新到 SwiftUI。再次感谢您的帮助:)【参考方案2】:

您可以尝试使用带有此类自定义修饰符的滚动视图来实现此功能:

struct ScrollViewPagingModifier: ViewModifier 
    func body(content: Content) -> some View 
        content
            .onAppear 
                UIScrollView.appearance().isPagingEnabled = true
            
            .onDisappear 
                UIScrollView.appearance().isPagingEnabled = false
            
    


extension ScrollView 
    func isPagingEnabled() -> some View 
        modifier(ScrollViewPagingModifier())
    

【讨论】:

以上是关于SwiftUI:如何在用户滑动时实现分页? (之前使用的 UICollectionView -> 启用分页)的主要内容,如果未能解决你的问题,请参考以下文章

如何在swift / SwiftUI中为滑动手势设置菜单栏图标的操作

滑动选项 swiftUI 滚动视图

如何在 SwiftUI 或无限列表视图中实现列表分页?

为 SwiftUI Apple Watch App 实现基于页面的导航

在 SwiftUI 中滑动列表时隐藏导航栏

SwiftUI 滑动 TabView 时如何访问 ScrollViewReader 的代理