BigUIPaging

用于处理内容分页的 SwiftUI 视图集合。

PageView

一个容器视图,用于管理相关视图之间的导航。

页面可以通过用户手势直接导航,也可以通过选择绑定或环境的导航操作以编程方式导航。

iOS

ScrollPageViewStyle.mp4
CardDeckPageViewStyle.mp4

macOS

ScrollPageViewStyle-mac.mp4

创建 PageView

有两种方法初始化 PageView。最简单的方法是使用 ForEach 数据源

@State private var selection: Int = 1

var body: some View {
    PageView(selection: $selection) {
        ForEach(1...10, id: \.self) { id in
            Text("Page \(value)")
        }
    }
    .pageViewStyle(.scroll)
}

或者,您可以使用 next 和 previous 闭包来返回相对于另一个值的值

@State private var selection: Int = 1

var body: some View {
    PageView(selection: $selection) { value in
        value + 1
    } previous: { value in
        value > 1 ? value - 1 : nil
    } content: { value in
        Text("Page \(value)")
    }
}

重要提示

默认情况下,页面视图没有手势或交互。您必须添加样式才能与之交互。

样式和过渡

确切的导航手势或过渡取决于所选样式。默认情况下,页面视图没有过渡或手势。

样式 iOS macOS
.plain
.scroll
.book
.historyStack
.bookStack
.cardDeck

您可以使用视图修饰符设置样式

PageView(selection: $selection) {
    ...
}
.pageViewStyle(.bookStack)

页面方向

支持垂直和水平导航(scrollbook)的样式可以使用方向视图修饰符进行配置

.pageViewOrientation(.vertical)

诸如 PageViewNavigationButton 之类的控件也会响应此修饰符,并根据需要调整 chevron 方向。

自定义样式

您可以创建自己完全自定义的页面视图过渡和交互。要创建自定义样式,请声明一个符合 PageViewStyle 协议的类型,并实现必需的 makeBody(configuration:) 方法。例如,以下是 plain 样式的实现方式

public struct PlainPageViewStyle: PageViewStyle {

   public init() { }

   public func makeBody(configuration: Configuration) -> some View {
       ZStack {
           configuration.content(configuration.selection.wrappedValue)
       }
   }
}

您可以使用 PageViewStyleConfiguration 结构来访问内容、next、previous 和当前选定的页面。

导航

除了使用选择绑定控制当前页面外,您还可以使用环境的 PageViewNavigateAction 操作来向后和向前导航页面视图。

@Environment(\.navigatePageView) private var navigate
@Environment(\.canNavigatePageView) private var canNavigate
    
var body: some View {
    Button {
        navigate(.forwards)
    } label: {
        Text("Next")
    }
    .disabled(!canNavigate.contains(.forwards))
}

还包括 PageViewNavigationButton,它提供了标准化的向前和向后控件

PageView {
    ...
}
.toolbar {
    ToolbarItem {
        PageViewNavigationButton()
            .pageViewOrientation(.vertical)
    }
}
.pageViewEnvironment()

PageIndicator

一个显示水平点系列的控件,每个点对应一个页面。

Page indicator

您可以通过设置总页数并传递到某些选择状态的绑定来创建页面指示器

@State private var selection = 1

var body: some View {
    PageIndicator(selection: $selection, total: 5)
}

此控件直接桥接到 iOS 上的 UIPageControl

指示器外观

您可以使用许多样式修饰符来控制指示器的外观

/// The tint color to apply to the page indicator.
.pageIndicatorColor(.purple)

/// The tint color to apply to the current page indicator.
.pageIndicatorCurrentColor(.pink)

/// A Boolean value that determines whether the page control allows continuous interaction.
.allowsContinuousInteraction(true)

/// The preferred background style.
.pageIndicatorBackgroundStyle(.prominent)

/// Controls whether the page indicator is hidden when there is only one page.
.singlePageVisibility(.hidden)

页面进度

页面指示器可以在设定的持续时间后自动前进到下一页。

PageIndicator...
    .pageIndicatorDuration(3.0)

如果选择绑定在两个视图之间共享,则也可以使用此功能来驱动 PageView

指示器图标

您可以自定义指示器的图标以表示特殊页面,例如 Weather 应用程序如何使用第一页来表示用户的当前位置

Page indicator

图标自定义以视图构建器的形式提供。第一个参数表示页面索引,第二个参数表示选定状态。

// Vary icons depending on page
PageIndicator(selection: $selection, total: total) { (page, selected) in
    if page == 0 {
        Image(systemName: "location.fill")
    }
}

// Vary icons depending on selection state
PageIndicator(selection: $selection, total: total) { (page, selected) in
    if selected {
        Image(systemName: "folder.fill")
    } else {
        Image(systemName: "folder")
    }
}

注意

目前仅支持 systemName 初始化器。


安装

BigUIPaging 可作为 Swift 包使用。只需将此存储库添加到您的 Package.swift 文件中

.package(url: "https://github.com/notsobigcompany/BigUIPaging.git", from: "0.0.1")

如果您要添加到 Xcode 项目,请转到 File -> Add Packages,然后将包链接到您所需的目标。

系统要求

示例代码

查看包内的 Examples 文件夹并打开 Xcode Preview Canvas。

您还可以在文档中找到示例代码。

FAQ

为什么使用 PageView 而不是 TabView?

PageView 旨在用于导航大量视图,其中所有页面可能在初始加载时都未知。 next 和 previous 闭包允许“动态”决定页面。

PageView 还可以正确处理更复杂的布局,例如,如果您的应用程序使用 NavigationStackNavigationSplitView。滚动事件会正确转发到视图层次结构,并且工具栏项目不会受到干扰。

通过采用 PageViewStyle,可以实现无限的过渡和交互可能性。

最后,PageView 在所有平台上都具有一致的行为,而 TabView 仅在 iOS 上支持分页。

PageView 是否使用 UIPageViewController/NSPageController?

在底层,某些样式(例如 scroll 和 history)分别直接桥接到 UIPageViewControllerNSPageController

许可证

版权所有 2023 NOT SO BIG TECH LIMITED

特此授予许可,免费向任何获得本软件及相关文档文件(“软件”)副本的人员授予许可,以处理本软件,不受限制,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售软件副本的权利,并允许向其提供软件的人员这样做,但须符合以下条件

上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。

本软件按“原样”提供,不提供任何形式的明示或暗示的保证,包括但不限于适销性、特定用途的适用性和不侵权的保证。在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是在合同诉讼、侵权诉讼或其他诉讼中,由软件或软件的使用或其他交易引起、产生或与之相关的责任。