作为一名iOS开发者,大家必定都触摸和运用过很多分页视图,也必定用过许多优秀的第三方分页视图组件例如JXPagingView等,但是笔者在实践的开发中遇到了全新的需求,如下图所示:
contentView要求要跳过tab栏,那么市面上已有的pageView组件便都不能满意这个要求了。 本文将介绍一种contentView跳过tab栏的pageView完成思路。
为了能够更快的完成需求,自己决议不运用相似JXPagingView的完成办法,以极简的办法快速完成需求。同时为了便利与同事间的协作,最终选择了UIPageViewController作为底层的滚动视图来接受各个tab下的uiviewcontroller。
有关UIPageViewController的介绍请查阅:blog.csdn.net/HDFQQ188816…
接下来我们直接看怎么完成上述效果:
//1.创建一个uiviewcontroller的实例,并完成相关协议
class BaseViewController:UIViewController,UIPageViewControllerDelegate,UIPageViewControllerDataSource{
//界说UIPageViewController的实例
private var pageViewController:UIPageViewController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
//用于保存contentViewControllers
private var controllers = [UIViewController]()
//获取索引
private var currentIndex:Int = 0;
//界说一个tab视图
private let categoryView:FindBaseCategoryView = FindBaseCategoryView.init(frame: CGRect.init(x: 0, y: 94, width: screenWidth, height: FitX(value: 51.5)))
//这儿界说了一个数据源,当数据源刷新时,初始化pageViewController
private var titles:[String] = []{
didSet{
pageViewController.view.frame = CGRect(x: 0, y: 0, width: (UIScreen.main.bounds.width), height: (UIScreen.main.bounds.height))
pageViewController.view.backgroundColor = .clear
pageViewController.delegate = self
pageViewController.dataSource = self
pageViewController.view.backgroundColor = .white
addChild(pageViewController)
view.addSubview(pageViewController.view)
pageViewController.didMove(toParent: self)
view.gestureRecognizers = pageViewController.gestureRecognizers
pageViewController.setViewControllers([controllers[0]], direction: .forward, animated: false)
self.view.addSubview(categoryView)
self.categoryView.titles = self.titles
}
}
}
下面完成UIPageViewController滑动手势的代理办法,每次代理事情完毕就刷新数据源
//往左边滑动翻页会走此办法(相似pop回来)
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController?{
let index = self.controllers.firstIndex(of: viewController)
if (index == 0) || (index == NSNotFound) {
return nil
}
//看护,避免空值在解包时溃散
guard let index1 = index else {
return nil
}
return controllers[index1 - 1]
}
//往左边滑动翻页会走此办法(相似push下去)
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController?{
//获取当时操控器索引
let index = self.controllers.firstIndex(of: viewController)
if index == NSNotFound {
return nil
}
if (index == self.controllers.count-1) {
//避免越界,必须要设置
return nil
}
//看护,避免空值在解包时溃散
guard let index1 = index else {
return nil
}
return controllers[index1+1]
}
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
let controller = pageViewController.viewControllers?[0] ?? UIViewController.init()
let index = controllers.firstIndex(of: controller)
categoryView.currentIndex = index
currentIndex = index ?? 0
self.setNavStatus()
}
此外,当点击上面的tab切换page的时分,要操控pageViewController滚动到对应方位,并且刷新数据,代码示例如下:
override func viewDidLoad() {
super.viewDidLoad()
viewModel.getData { model in
self.configControllers(knowTabs: model?.discTabs ?? [])
}
categoryView.clickClosure = {index in
if self.currentIndex < index{
self.pageViewController.setViewControllers([self.controllers[index]], direction: .forward, animated: true)
}else{
self.pageViewController.setViewControllers([self.controllers[index]], direction: .reverse, animated: true )
}
self.currentIndex = index
}
上面代码中configControllers()办法是构建controllers和tabs数据的办法,大致完成如下:
private func configControllers(knowTabs:[Tab]){
if knowTabs.isEmpty{
return
}
controllers.removeAll()
var myTitles = [String]()
for index in 0..<knowTabs.count{
let model = knowTabs[index]
let vc = UIViewController.init()
controllers.append(vc)
myTitles.append(model.title)
}
self.titles = myTitles
}
至此,极简版通顶分页视图的首要代码便完成完了,如果有什么疑问,欢迎留言向我提问。