概述
UIPageViewController
可以实现内容页之间的导航功能,每一页的内容都由它自己的view controller来管理。
页面过渡有两种方式:
- UIPageViewControllerTransitionStyle.PageCurl(卷曲翻页)
- UIPageViewControllerTransitionStyle.Scroll(滚动)
.PageCurl
当以此方式过渡页面的时候,UIPageViewController
的属性spineLocation
(书脊的位置),和doubleSided
(双面)来共同决定要展示的页面是一个,还是两个。通过方法
- setViewControllers:direction:animated:completion:
来展示需要的页面,参数 `viewControllers
根据下表的具体情况来设置。
Spline location | Double sided | whate to pass |
---|---|---|
.Mid(中间位置) | true | 传要显示的左边页面和右边页面 |
.Min .Max | true | 传将要显示页面的前页面和后页面,后页面用于动画 |
.Min or .Max | false | 传将要显示页面的前面页面 |
书脊位置定义如下:
enum UIPageViewControllerSpineLocation : Int
{
case None //位置无效
case Min //屏幕左边或上边缘,显示一个view controller
case Mid //屏幕中间,显示两个view controller
case Max //屏幕右边或下边缘,显示一个view controller
}
下图展示一页
下图展示双页的情况,书脊在中间位置
代码示例
let pageViewController = UIPageViewController(transitionStyle: .PageCurl, navigationOrientation: .Horizontal, options: nil)
let currentViewController = self.pageViewController!.viewControllers![0]
let viewControllers = [currentViewController]
self.pageViewController!.setViewControllers(viewControllers, direction: .Forward, animated: true, completion: {done in })
self.pageViewController!.doubleSided = false
特性
在此过渡模式下,页指示器控件: UIPageControl
(详情点这里)是不显示的。
.Scroll
此模式下不支持一次显示两个页面,但可以通过实现soureData
的两个方法:
来展示页指示器控件。
- presentationCountForPageViewController: 和
- presentationIndexForPageViewController:
在 iphone 6s下运行效果图如下:
在iPad Pro环境下运行效果如下:
dataSource(数据源)
数据源的方法是被以手势进行的导航调用的,如果不设置此属性,则手势导航无效。
它遵循UIPageViewControllerDataSource
协议,确定什么内容被展示,创建需要的内容。
它有四个方法,功能示例如下:
//给定页面的上一个页面
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
var index = self.indexOfViewController(viewController as! DataViewController)
if (index == 0) || (index == NSNotFound) {
return nil
}
index--
return self.viewControllerAtIndex(index, storyboard: viewController.storyboard!)
}
//给定页面的下一个页面
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
var index = self.indexOfViewController(viewController as! DataViewController)
if index == NSNotFound {
return nil
}
index++
if index == self.pageData.count {
return nil
}
return self.viewControllerAtIndex(index, storyboard: viewController.storyboard!)
}
//配置页指示器总数
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return pageData.count
}
// 当前页指示器索引
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
return 0
}
delegate(代理)
遵循 UIPageViewControllerDelegate
协议,当用手势导航页面和设备方向发生改变的时候会调用它的方法。
主要方法及功能如下:
//设置书脊的位置
func pageViewController(pageViewController: UIPageViewController, spineLocationForInterfaceOrientation orientation: UIInterfaceOrientation) -> UIPageViewControllerSpineLocation {
if (orientation == .Portrait) || (orientation == .PortraitUpsideDown) || (UIDevice.currentDevice().userInterfaceIdiom == .Phone) {
// In portrait orientation or on iPhone: Set the spine position to "min" and the page view controller's view controllers array to contain just one view controller. Setting the spine position to 'UIPageViewControllerSpineLocationMid' in landscape orientation sets the doubleSided property to true, so set it to false here.
let currentViewController = self.pageViewController!.viewControllers![0]
let viewControllers = [currentViewController]
self.pageViewController!.setViewControllers(viewControllers, direction: .Forward, animated: true, completion: {done in })
self.pageViewController!.doubleSided = false
return .Min
}
let currentViewController = self.pageViewController!.viewControllers![0] as! DataViewController
var viewControllers: [UIViewController]
let indexOfCurrentViewController = self.modelController.indexOfViewController(currentViewController)
if (indexOfCurrentViewController == 0) || (indexOfCurrentViewController % 2 == 0)
{
let nextViewController = self.modelController.pageViewController(self.pageViewController!, viewControllerAfterViewController: currentViewController)
viewControllers = [currentViewController, nextViewController!]
} else {
let previousViewController = self.modelController.pageViewController(self.pageViewController!, viewControllerBeforeViewController: currentViewController)
viewControllers = [previousViewController!, currentViewController]
}
self.pageViewController!.setViewControllers(viewControllers, direction: .Forward, animated: true, completion: {done in })
return .Mid
}
// 将要翻页
func pageViewController(pageViewController: UIPageViewController, willTransitionToViewControllers pendingViewControllers: [UIViewController]) {
print("willTransition")
}
//翻页完成,如果翻页过程中取消翻页,则completed= false
func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
print("finishTransition: finished : \(finished), completed: \(completed)")
}