UIPageViewController
UIPageViewController
是一個(gè)用來管理內(nèi)容頁之間導(dǎo)航的容器控制器(container view controller)佃牛,其中每個(gè)子頁面由子視圖控制器管理攘蔽。內(nèi)容頁間導(dǎo)航可以由用戶手勢(shì)觸發(fā),也可以由代碼控制贰剥。
UIPageViewController
可以實(shí)現(xiàn)圖片輪播效果和翻書效果.
初始化PageViewController
public init(transitionStyle style: UIPageViewController.TransitionStyle,
navigationOrientation: UIPageViewController.NavigationOrientation,
options: [UIPageViewController.OptionsKey : Any]? = nil)
初始化方法提供三個(gè)參數(shù):
- TransitionStyle
UIPageViewController翻頁的過渡樣式
public enum TransitionStyle : Int {
case pageCurl // Navigate between views via a page curl transition. 卷曲樣式類似翻書效果
case scroll // Navigate between views by scrolling. UIScrollView滾動(dòng)效果
}
- NavigationOrientation
UIPageViewController導(dǎo)航方向
public enum NavigationOrientation : Int {
case horizontal // 水平導(dǎo)航
case vertical // 垂直導(dǎo)航
}
- UIPageViewController.OptionsKey
這個(gè)參數(shù)是可選的,傳入的是對(duì)UIPageViewController的一些配置
public struct OptionsKey : Hashable, Equatable, RawRepresentable {
public init(rawValue: String)
}
extension UIPageViewController.OptionsKey {
public static let spineLocation: UIPageViewController.OptionsKey
// Key for specifying spacing between pages in options dictionary argument to initWithTransitionStyle:navigationOrientation:options:.
// Value should be a CGFloat wrapped in an NSNumber. Default is '0'.
// Only valid for use with page view controllers with transition style 'UIPageViewControllerTransitionStyleScroll'.
@available(iOS 6.0, *)
public static let interPageSpacing: UIPageViewController.OptionsKey
}
- spineLocation
這個(gè)key
只有在TransitionStyle
是翻書效果pageCurl
的時(shí)候才有作用, 它定義的是書脊的位置,值對(duì)應(yīng)著SpineLocation
枚舉锅减,默認(rèn)值為UIPageViewController.SpineLocation.min
public enum SpineLocation : Int {
case none // Returned if 'spineLocation' is queried when 'transitionStyle' is not 'UIPageViewControllerTransitionStylePageCurl'.
case min // Requires one view controller.
case mid // Requires two view controllers.
case max // Requires one view controller.
}
- interPageSpacing
這個(gè)key
只有在TransitionStyle
是UIScrollView
滾動(dòng)效果scroll
的時(shí)候才有作用, 它定義的是兩個(gè)頁面之間的間距(默認(rèn)間距是0)
數(shù)據(jù)源和代理
數(shù)據(jù)源提供了UIPageViewController
內(nèi)容
weak open var dataSource: UIPageViewControllerDataSource? // If nil, user gesture-driven navigation will be disabled.
UIPageViewControllerDataSource
協(xié)議
public protocol UIPageViewControllerDataSource : NSObjectProtocol {
@available(iOS 5.0, *)
public func pageViewController(_ pageViewController: UIPageViewController,
viewControllerBefore viewController: UIViewController) -> UIViewController?
@available(iOS 5.0, *)
public func pageViewController(_ pageViewController: UIPageViewController,
viewControllerAfter viewController: UIViewController) -> UIViewController?
@available(iOS 6.0, *)
// The number of items reflected in the page indicator.
optional public func presentationCount(for pageViewController: UIPageViewController) -> Int
@available(iOS 6.0, *)
// The selected item reflected in the page indicator.
optional public func presentationIndex(for pageViewController: UIPageViewController) -> Int
}
協(xié)議中包含了四個(gè)方法,其中兩個(gè)為@required,另外兩個(gè)是@optional.
public func pageViewController(_ pageViewController: UIPageViewController,
viewControllerBefore viewController: UIViewController) -> UIViewController?
該方法是返回前一個(gè)頁面辐董,如果返回為nil,那么UIPageViewController
就會(huì)認(rèn)為當(dāng)前頁面是第一個(gè)頁面不可以向前滾動(dòng)或翻頁白对。當(dāng)NavigationOrientation
為horizontal
時(shí)掠廓,那么該方法獲得當(dāng)前頁面左邊的視圖控制器
public func pageViewController(_ pageViewController: UIPageViewController,
viewControllerAfter viewController: UIViewController) -> UIViewController?
該方法返回后一個(gè)頁面,如果返回為nil甩恼,那么UIPageViewController
就會(huì)認(rèn)為當(dāng)前頁面是最后一個(gè)頁面不可以向后滾動(dòng)或翻頁蟀瞧。當(dāng)NavigationOrientation
為horizontal
時(shí),那么該方法獲得是當(dāng)前頁面右邊的視圖控制器
代理(delegate)自定義UIPageViewController
的行為
weak open var delegate: UIPageViewControllerDelegate?
UIPageViewControllerDelegate
協(xié)議
public protocol UIPageViewControllerDelegate : NSObjectProtocol {
@available(iOS 6.0, *)
optional public func pageViewController(_ pageViewController: UIPageViewController,
willTransitionTo pendingViewControllers: [UIViewController])
@available(iOS 5.0, *)
optional public func pageViewController(_ pageViewController: UIPageViewController,
didFinishAnimating finished: Bool,
previousViewControllers: [UIViewController],
transitionCompleted completed: Bool)
@available(iOS 5.0, *)
optional public func pageViewController(_ pageViewController: UIPageViewController,
spineLocationFor orientation: UIInterfaceOrientation) -> UIPageViewController.SpineLocation
@available(iOS 7.0, *)
optional public func pageViewControllerSupportedInterfaceOrientations(_ pageViewController: UIPageViewController) -> UIInterfaceOrientationMask
@available(iOS 7.0, *)
optional public func pageViewControllerPreferredInterfaceOrientationForPresentation(_ pageViewController: UIPageViewController) -> UIInterfaceOrientation
}
協(xié)議中有5各方法
optional public func pageViewController(_ pageViewController: UIPageViewController,
willTransitionTo pendingViewControllers: [UIViewController])
該方法是UIPageViewController
開始滾動(dòng)或翻頁的時(shí)候觸發(fā)
optional public func pageViewController(_ pageViewController: UIPageViewController,
didFinishAnimating finished: Bool,
previousViewControllers: [UIViewController],
transitionCompleted completed: Bool)
該方法是在UIPageViewController
結(jié)束滾動(dòng)或翻頁的時(shí)候觸發(fā)
optional public func pageViewController(_ pageViewController: UIPageViewController,
spineLocationFor orientation: UIInterfaceOrientation) -> UIPageViewController.SpineLocation
該方法在TransitionStyle
是pageCurl
并且橫豎屏狀態(tài)變化的時(shí)候觸發(fā)条摸,我們可以重新設(shè)置書脊的位置悦污,比如:如果屏幕是豎屏狀態(tài)的時(shí)候我們就設(shè)置書脊位置是min或max, 如果屏幕是橫屏狀態(tài)的時(shí)候我們可以設(shè)置書脊位置是mid
最后兩個(gè)方法設(shè)置了UIPageViewController
支持的屏幕類型
重要的方法和屬性
isDoubleSided
屬性默認(rèn)為NO,如果我們當(dāng)前屏幕僅展示一個(gè)頁面那么不用設(shè)置這個(gè)屬性钉蒲,如果設(shè)置了UIPageViewControllerSpineLocationMid
這個(gè)選項(xiàng)切端,效果是翻開的書這樣屏幕展示的就是兩個(gè)頁面,這個(gè)屬性就必須設(shè)置為true
了.
open var isDoubleSided: Bool // Default is 'NO'.
setViewControllers
open func setViewControllers(_ viewControllers: [UIViewController]?,
direction: UIPageViewController.NavigationDirection,
animated: Bool,
completion: ((Bool) -> Void)? = nil)
這個(gè)方法是設(shè)置UIPageViewController
初始顯示的頁面顷啼,如果doubleSided
設(shè)為true
了,那么viewControllers這
個(gè)參數(shù)至少包含兩個(gè)視圖控制器
NavigationDirection
// Only pertains to 'UIPageViewControllerTransitionStylePageCurl'.
public enum NavigationDirection : Int {
case forward // 導(dǎo)航到下一個(gè)頁面
case reverse // 導(dǎo)航到上一個(gè)頁面
}
使用
簡(jiǎn)單的實(shí)現(xiàn)滑動(dòng)切換視圖踏枣,即輪播圖
class PageViewController: UIViewController {
// 懶加載創(chuàng)建UIPageViewController
lazy var pageViewController: UIPageViewController = {
// 設(shè)置水平滾動(dòng)
let pageVc = UIPageViewController(transitionStyle: .scroll,
navigationOrientation: .horizontal,
options: nil)
pageVc.dataSource = self
pageVc.delegate = self
return pageVc
}()
// 簡(jiǎn)單的3個(gè)UIViewController
var viewControllers: [UIViewController] {
return [RedViewController(), YellowViewController(), BlueViewController()]
}
var currentIndex: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
addPageViewController()
// 設(shè)置初始化顯示視圖控制器
pageViewController.setViewControllers([viewControllers[currentIndex]],
direction: .forward,
animated: true,
completion: nil)
}
func addPageViewController() {
self.addChild(pageViewController)
pageViewController.view.frame = self.view.frame
view.addSubview(pageViewController.view)
pageViewController.didMove(toParent: self)
}
}
擴(kuò)展PageViewController實(shí)現(xiàn)數(shù)據(jù)源和代理協(xié)議
extension PageViewController: UIPageViewControllerDataSource, UIPageViewControllerDelegate {
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
// 顯示前一個(gè)頁面,保證數(shù)組不越界
if currentIndex - 1 >= 0 {
currentIndex -= 1
return viewControllers[currentIndex]
}
return nil
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
// 顯示后一個(gè)視圖頁面
if currentIndex + 1 < viewControllers.count {
currentIndex += 1
return viewControllers[currentIndex]
}
return nil
}
func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
print("willTransition - 開始滾動(dòng)")
}
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
print("didFinishAnimating - 結(jié)束滾動(dòng)")
}
}
實(shí)現(xiàn)效果如下
相關(guān)實(shí)戰(zhàn)
-
Parchment
68747470733a2f2f73332d75732d776573742d312e616d617a6f6e6177732e636f6d2f70617263686d656e742d73776966742f70617263686d656e742d64656c65676174652e676966.gif
68747470733a2f2f73332d75732d776573742d312e616d617a6f6e6177732e636f6d2f70617263686d656e742d73776966742f70617263686d656e742d756e73706c6173682e676966.gif