PagerTabStripView: First pager view built in pure SwiftUI

build and test Platform iOS Swift 5 compatible Carthage compatible CocoaPods compatible License: MIT

用 ❤️ 由 Xmartlabs 团队制作。适用于 SwiftUI 的 XLPagerTabStrip

简介

PagerTabStripView 是第一个完全使用 SwiftUI 构建的页面视图。它提供了一个组件来创建包含子视图的交互式页面视图。它允许用户通过滑动或点击标签栏项目在视图之间切换。

与 Apple 的 TabView 不同,它提供了

  1. 灵活的方式来完全自定义页面标签视图。
  2. 每个 pagerTabItem 视图可以是不同的类型。
  3. 包含页面标签项的栏放置在顶部。
  4. 指示器视图指示选定的子视图。
  5. 能够根据高亮、选中、正常状态更新 pagerTabItem。
  6. 能够在另一个页面中嵌入一个页面,并且不破坏滚动行为。
  7. 能够根据页面选择和页面之间的过渡进度更新 UI。

用法

创建页面视图非常简单,您只需要将自定义标签视图放入 PagerTabStripView 视图中,并对每个视图应用 pagerTabItem 修饰符以指定其导航栏标签项。tag 参数是标识标签项的值。它可以是任何 Hashable 值,并且必须是唯一的。

import PagerTabStripView

struct MyPagerView: View {

    var body: some View {

        PagerTabStripView() {
            MyFirstView()
                .pagerTabItem(tag: 1) {
                    TitleNavBarItem(title: "Tab 1")
                }
            MySecondView()
                .pagerTabItem(tag: 2) {
                    TitleNavBarItem(title: "Tab 2")
                }
            if User.isLoggedIn {
                MyProfileView()
                    .pagerTabItem(tag: 3) {
                        TitleNavBarItem(title: "Profile")
                    }
            }
        }

    }
}


要指定初始选定的页面,您可以传递 selection 初始化参数(为了使其正常工作,此值必须等于标签项的某些 tag 值)。

struct MyPagerView: View {

    @State var selection = 1

    var body: some View {
        PagerTabStripView(selection: $selection) {
            MyFirstView()
                .pagerTabItem(tag: 1) {
                    TitleNavBarItem(title: "Tab 1")
                }
            ...
            ..
            .
        }
    }
}

正如您可能已经注意到的,一切都是 SwiftUI 代码,因此您可以根据 SwiftUI 状态对象更新子视图,如上面的 if User.isLoggedIn 所示。

用户还可以配置是否启用滑动操作(滑动基于拖动手势),并设置禁用手势的边缘。

参数

为什么这个参数很重要?这个参数在 MyPagerView2 中的下一个 PagerTabStripView 示例中很重要。如果页面在第一页并且用户尝试向左滑动,则父视图容器可能会被触发,而不是页面的滑动 gesture,因为拖动手势可以捕获父视图手势。edgeSwipeGestureDisabled 参数可以防止这种情况发生。

struct MyPagerView2: View {

    @State var selection = 1

    var body: some View {
        PagerTabStripView(edgeSwipeGestureDisabled: .constant([.left]),
			  selection: $selection) {
            MyFirstView()
                .pagerTabItem(tag: 1) {
                    TitleNavBarItem(title: "Tab 1")
                }
            ...
            ..
            .
        }
    }
}

自定义页面样式

PagerTabStripView 提供了 5 种不同的方式来显示视图,可以使用 pagerTabStripViewStyle 修饰符选择和自定义这些方式。

可滚动样式

此样式允许您添加任意数量的页面。对于大量页面,标签放置在水平滚动条内。

可自定义的设置包括

struct PagerView: View {

    @State var selection = 1

	var body: some View {
		PagerTabStripView(selection: $selection) {
			MyView()
				.pagerTabItem(tag: 1) {
					TitleNavBarItem(title: "First big width")
				}
			AnotherView()
				.pagerTabItem(tag: 2) {
					TitleNavBarItem(title: "Short")
				}
            ...
            ..
            .

		}
        .pagerTabStripViewStyle(.scrollableBarButton(tabItemSpacing: 15, 
						     tabItemHeight: 50, 
	    					     indicatorView: {
            						Rectangle().fill(.blue).cornerRadius(5)
            					     }))
	}
}

在此示例中,我们添加了一些设置,例如标签栏高度、指示器视图和标签项间距。让我们看看它的外观!

按钮栏样式

此样式将所有 TabBar 项目放置在一个容器中,每个项目具有相同的宽度。它非常适合 2-4 页的页面。可以自定义与 Scrollable 样式相同的设置。

可自定义的设置包括

struct PagerView: View {

    @State var selection = "Tab 1"

	var body: some View {
		PagerTabStripView(selection: $selection) {
			MyView()
				.pagerTabItem(tag: "Tab 1") {
					TitleNavBarItem(title: "Tab 1")
				}
			AnotherView()
				.pagerTabItem(tag: "Tab 2") {
					TitleNavBarItem(title: "Tab 2")
				}
			if User.isLoggedIn {
				ProfileView()
					.pagerTabItem(tag: "Profile") {
						TitleNavBarItem(title: "Profile")
                    }
			}
		}
        .pagerTabStripViewStyle(.barButton(tabItemSpacing: 15, 
					   tabItemHeight: 50, 
	    			           indicatorView: {
            				   	Rectangle().fill(.gray).cornerRadius(5)
            				   }))
	}
}

在此示例中,我们添加了一些设置,例如标签栏高度、指示器视图和指示器栏高度。让我们看看它的外观!

栏样式

此样式仅显示一个指示当前选定页面的栏。

可自定义的设置包括

分段样式

此样式使用分段选择器来指示选定的页面。您可以指示分段颜色、其内边距以及是否要将其放置在工具栏中。

可自定义的设置包括

自定义样式

我们可以通过使用 bar 和 scrollablebar 样式并提供表示指示器和标签栏容器视图的自定义视图来构建任何自定义样式。查看下面的示例。示例应用程序中还有其他一些示例。

        .pagerTabStripViewStyle(.barButton(placedInToolbar: false,
                                           pagerAnimation: .interactiveSpring(response: 0.5,
                                                                              dampingFraction: 1.00,
                                                                              blendDuration: 0.25),
                                           tabItemHeight: 48,
                                           barBackgroundView: {
            LinearGradient(
               colors: 🌈,
               startPoint: .topLeading,
               endPoint: .bottomTrailing
           )
           .opacity(0.2)
        }, indicatorView: {
            Text("👍🏻").offset(x: 0, y: -24)
        }))

查看效果

导航栏

导航栏支持每个页面的自定义标签栏视图。您可以在 pagerTabItem 修饰符内联指定每个标签栏项目,或者通过遵循 View 协议在独立的结构中指定。

为了简单起见,我们将实现一个仅包含标题的导航栏项目。您可以在示例应用程序中找到更多示例。

struct TitleNavBarItem: View {
    let title: String

    var body: some View {
        VStack {
            Text(title)
                .foregroundColor(Color.gray)
                .font(.subheadline)
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(Color.white)
    }
}

示例

按照以下 3 个步骤运行示例项目

安装

CocoaPods

要使用 CocoaPods 安装 PagerTabStripView,只需将以下行添加到您的 Podfile

pod 'PagerTabStripView', '~> 4.0'

Carthage

要使用 Carthage 安装 PagerTabStripView,只需将以下行添加到您的 Cartfile

github "xmartlabs/PagerTabStripView" ~> 4.0

要求

作者

参与贡献

在贡献代码之前,请务必查看 CONTRIBUTING 文件以获取更多信息。

我们很乐意听到您使用 PagerTabStripView 的体验。如果您在您的应用程序中使用它,请在 Twitter 上给我们留言。