XLPagerTabStrip
使用
为 iOS 制作,参考 Android PagerTabStrip!
XLPagerTabStrip 是一个 容器视图控制器,使我们可以轻松在多个视图控制器集合之间切换。可以使用滑动手势来移到下一个或上一个视图控制器。它显示当前、上一个和下一个子视图控制器的交互式指示器。
参与
- 如果您 想要贡献力量,请随时 提交拉取请求。
- 如果您 有功能请求,请 打开问题。
- 如果您 发现了错误或 需要帮助,请在提交问题之前 检查旧问题、常见问题解答 和 StackOverflow (标签 'XLPagerTabStrip')上的线程。
在贡献之前,请检查 CONTRIBUTING 文件以获取更多信息。
如果您在您的应用程序中使用了 XLPagerTabStrip,我们非常愿意听到您的反馈!在 twitter 上给我们留言。
页面类型
该库提供了 4 种不同的方式来显示视图控制器。
按钮栏
这可能是最常见的分页器类型。它被许多知名应用程序如instagram、youtube、skype等所使用。
栏
这种模式不显示标题也不显示图像。它只显示一个指示当前视图控制器的栏。
微博
很久以前,微博应用程序在应用主界面使用了这种类型的分页器。
分割标签页
这种模式使用UISegmentedControl
来指示正在显示的视图控制器。
用法
基本上,我们只需要提供要显示的子视图控制器的列表,并且这些视图控制器应该提供将显示在相关指示器中的信息(标题或图像)。
让我们看看如何操作的步骤
选择我们想要创建的分页器类型
首先,我们必须选择我们想要创建的分页器类型。根据我们的选择,我们需要创建一个控制器,该控制器可以从以下控制器之一扩展:TwitterPagerTabStripViewController
、ButtonBarPagerTabStripViewController
、SegmentedPagerTabStripViewController
、BarPagerTabStripViewController
。
所有这些内置的分页器控制器都扩展自基本类
PagerTabStripViewController
。如果没有任何分页菜单类型符合您的需求,您也可以通过直接从PagerTabStripViewController
扩展来自定义分页器控制器。
import XLPagerTabStrip
class MyPagerTabStripName: ButtonBarPagerTabStripViewController {
..
}
连接输出并添加布局约束
我们强烈建议使用 IB 来设置分页控制器视图。
将一个 UIViewController
拖入故事板,并将其类设置为您的分页控制器(《MyPagerTabStripName》)。将一个 UIScrollView
拖入视图控制器视图中,并将 PagerTabStripViewController
的 containerView
输出与滚动视图连接。
根据您正在使用的分页视图控制器的类型,您可能需要连接更多的输出。
对于 BarPagerTabStripViewController
,我们应该连接 barView
输出。barView 类型是 UIView。对于 ButtonBarPagerTabStripViewController
,我们需要连接 buttonBarView
输出。buttonBarView 类型是继承自 UICollectionView
的 ButtonBarView
。对于 SegmentedPagerTabStripViewController
,有一个 segmentedControl
输出;如果连接不上输出,库将尝试使用 UISegmentedControl
设置 navigationItem 的 titleView
属性。TwitterPagerTabStripViewController
不需要我们连接任何额外的输出。
示例项目包含对每种分页器控制器的示例,我们可以查看它以了解视图是如何添加和如何连接输出的。
提供将要嵌入到 PagerTabStrip 视图控制器中的视图控制器
您可以通过重写 func viewControllers(for: pagerTabStripController: PagerTabStripViewController) -> [UIViewController]
方法来提供视图控制器。
override public func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
return [MyEmbeddedViewController(), MySecondEmbeddedViewController()]
}
上面的方法是
PagerTabStripDataSource
协议中唯一声明的方法。我们不需要显式符合它,因为基本分页器类已经这样做了。
提供要显示在每个指示符中的信息
将要出现在 PagerTabStrip 中的每一个 UIViewController 都必须提供标题或图片。为了实现这一点,它们应该遵循 IndicatorInfoProvider
协议,通过实现 func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo
方法,这个方法提供了与视图控制器相关联的 PagerTabStrip 菜单(指示器)所需的信息。
class MyEmbeddedViewController: UITableViewController, IndicatorInfoProvider {
func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo {
return IndicatorInfo(title: "My Child title")
}
}
关于如何使用库的详细分步指南,请查看这篇社区博客:blog post。
这就结束了!我们已经完成!
自定义
分页器行为
分页指示器可以随着滑动逐步更新,或者在视图控制器之间的转换过程中一次性更新。通过设置 pagerBehaviour
属性,我们可以选择如何更新指示器。
public var pagerBehaviour: PagerTabStripBehaviour
public enum PagerTabStripBehaviour {
case common(skipIntermediteViewControllers: Bool)
case progressive(skipIntermediteViewControllers: Bool, elasticIndicatorLimit: Bool)
}
默认值
// Twitter Type
PagerTabStripBehaviour.common(skipIntermediateViewControllers: true)
// Segmented Type
PagerTabStripBehaviour.common(skipIntermediateViewControllers: true)
// Bar Type
PagerTabStripBehaviour.progressive(skipIntermediateViewControllers: true, elasticIndicatorLimit: true)
// ButtonBar Type
PagerTabStripBehaviour.progressive(skipIntermediateViewControllers: true, elasticIndicatorLimit: true)
你可能已经注意到,common
和 progressive
枚举情况相关联的值有 skipIntermediateViewControllers
和 elasticIndicatorLimit
。
skipIntermediateViewControllers
允许我们在点击标签指示器时跳过中间视图控制器。
elasticIndicatorLimit
允许我们在达到限制时拉紧指示器,我指的是在尝试从最后一个指示器向前移动或从第一个指示器向后移动时。
PagerTabStripDelegate & PagerTabStripIsProgressiveDelegate
通常我们不需要实现这些协议,因为每种分页类型已经遵循了它,以便正确更新其指示器。然而,在某些情况下,可能需要覆盖某个方法。
public protocol PagerTabStripDelegate: class {
func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int)
}
public protocol PagerTabStripIsProgressiveDelegate : PagerTabStripDelegate {
func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool)
}
同样,由库调用的方法取决于
pagerBehaviour
的值。
按钮栏自定义
settings.style.buttonBarBackgroundColor: UIColor?
// buttonBar minimumInteritemSpacing value, note that button bar extends from UICollectionView
settings.style.buttonBarMinimumInteritemSpacing: CGFloat?
// buttonBar minimumLineSpacing value
settings.style.buttonBarMinimumLineSpacing: CGFloat?
// buttonBar flow layout left content inset value
settings.style.buttonBarLeftContentInset: CGFloat?
// buttonBar flow layout right content inset value
settings.style.buttonBarRightContentInset: CGFloat?
// selected bar view is created programmatically so it's important to set up the following 2 properties properly
settings.style.selectedBarBackgroundColor = UIColor.black
settings.style.selectedBarHeight: CGFloat = 5
// each buttonBar item is a UICollectionView cell of type ButtonBarViewCell
settings.style.buttonBarItemBackgroundColor: UIColor?
settings.style.buttonBarItemFont = UIFont.systemFont(ofSize: 18)
// helps to determine the cell width, it represent the space before and after the title label
settings.style.buttonBarItemLeftRightMargin: CGFloat = 8
settings.style.buttonBarItemTitleColor: UIColor?
// in case the barView items do not fill the screen width this property stretch the cells to fill the screen
settings.style.buttonBarItemsShouldFillAvailiableWidth = true
// only used if button bar is created programmatically and not using storyboards or nib files as recommended.
public var buttonBarHeight: CGFloat?
重要:设置应在使用 viewDidLoad
调用之前进行。
override func viewDidLoad() {
self.settings.style.selectedBarHeight = 2
self.settings.style.selectedBarBackgroundColor = UIColor.white
super.viewDidLoad()
}
选中指示器更改时更新单元格
当显示的视图控制器更改时,我们可能需要更新指示器单元格。以下函数属性有助于实现这一点。根据我们的分页器 pagerBehaviour
值,我们将不得不设置 changeCurrentIndex
或 changeCurrentIndexProgressive
。
public var changeCurrentIndex: ((oldCell: ButtonBarViewCell?, newCell: ButtonBarViewCell?, animated: Bool) -> Void)?
public var changeCurrentIndexProgressive: ((oldCell: ButtonBarViewCell?, newCell: ButtonBarViewCell?, progressPercentage: CGFloat, changeCurrentIndex: Bool, animated: Bool) -> Void)?
让我们看一个示例
changeCurrentIndexProgressive = { (oldCell: ButtonBarViewCell?, newCell: ButtonBarViewCell?, progressPercentage: CGFloat, changeCurrentIndex: Bool, animated: Bool) -> Void in
guard changeCurrentIndex == true else { return }
oldCell?.label.textColor = UIColor(white: 1, alpha: 0.6)
newCell?.label.textColor = UIColor.white
if animated {
UIView.animate(withDuration: 0.1, animations: { () -> Void in
newCell?.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
oldCell?.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
})
}
else {
newCell?.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
oldCell?.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
}
}
条状类型定制
settings.style.barBackgroundColor: UIColor?
settings.style.selectedBarBackgroundColor: UIColor?
// barHeight is only set up when the bar is created programmatically and not using storyboards or xib files as recommended.
settings.style.barHeight: CGFloat = 5
Twitter 类型定制
settings.style.dotColor = UIColor(white: 1, alpha: 0.4)
settings.style.selectedDotColor = UIColor.white
settings.style.portraitTitleFont = UIFont.systemFont(ofSize: 18)
settings.style.landscapeTitleFont = UIFont.systemFont(ofSize: 15)
settings.style.titleColor = UIColor.white
分段类型定制
settings.style.segmentedControlColor: UIColor?
需求
- iOS 9.3+
- Xcode 10.2+
示例
按照以下3个步骤运行示例项目:克隆 XLPagerTabStrip 仓库,打开 XLPagerTabStrip 工作空间并运行 示例 项目。
安装
CocoaPods
CocoaPods 是 Cocoa 项目的依赖管理器。
要安装 XLPagerTabStrip,只需在 Podfile 中添加以下行
pod 'XLPagerTabStrip', '~> 9.0'
Carthage
Carthage 是一个简单、去中心化适用于 Cocoa 的依赖管理器。
要安装 XLPagerTabStrip,只需在 Cartfile 中添加以下行
github "xmartlabs/XLPagerTabStrip" ~> 9.0
常见问题解答
如何通过代码更改可见的子视图控制器
PagerTabStripViewController
提供以下方法来通过代码更改可见的子视图控制器
func moveToViewController(at index: Int)
func moveToViewController(at index: Int, animated: Bool)
func moveTo(viewController: UIViewController)
func moveTo(viewController: UIViewController, animated: Bool)
如何从 Swift 2 迁移到 Swift 3
请参阅 我们的迁移指南
作者
变更日志
可以在CHANGELOG.md文件中找到。