问题:
当做一个电子阅读器时,需要横屏显示两页,竖屏显示一页,该如何做?
解决方案:
你可以使用官方代理的方法:
func pageViewController(_ pageViewController: UIPageViewController, spineLocationFor orientation: UIInterfaceOrientation) -> UIPageViewControllerSpineLocation {
}
官方文档上描述了这个代理方法
// Delegate may specify a different spine location for after the interface orientation change. Only sent for transition style //'UIPageViewControllerTransitionStylePageCurl'.
也就是说当屏幕方向转变后,如果当前PageViewController的transitionStyle是pageCurl模式,会调用这个方法。
我遇到的问题就是我的pageViewController设置了pageCurl模式,屏幕方向转变后,并没有调用func pageViewController(_ pageViewController: UIPageViewController, spineLocationFor orientation: UIInterfaceOrientation) -> UIPageViewControllerSpineLocation {}
最后找出了原因:
我当前的viewController是继承于UIViewController的,将pageViewController.view加到当前view上,这样是不触发
func pageViewController(_ pageViewController: UIPageViewController, spineLocationFor orientation: UIInterfaceOrientation) -> UIPageViewControllerSpineLocation {}
这个代理方法的,只有当前的viewController继承于UIPageViewController,才能触发这个代理方法。
下面贴出代码
当前界面父类是UIViewController
import UIKitclass ZHViewController: UIViewController { var dataArray : Array= []
var pageViewController : UIPageViewController?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.white
// Do any additional setup after loading the view.
prepareData()
pageViewControllerConfig()
}
func prepareData(){
for i in 0 ..< 20 {
let page = BaseModel()
page.viewController = ZHSubViewController()
page.viewController?.currentPage = i
dataArray.append(page)
}
}
func pageViewControllerConfig(){
pageViewController = UIPageViewController.init(transitionStyle: UIPageViewControllerTransitionStyle.pageCurl, navigationOrientation: UIPageViewControllerNavigationOrientation.horizontal, options: nil)
setOnePage()
pageViewController?.delegate = self
pageViewController?.dataSource = self
pageViewController?.view.frame = view.bounds
view.addSubview(pageViewController!.view!)
}
func setOnePage(){
let vc = dataArray[0].viewController
pageViewController?.setViewControllers([vc!], direction: UIPageViewControllerNavigationDirection.forward, animated: false, completion: nil)
}
func setDoublePage(){
let vc = dataArray[0].viewController
let nextVc = dataArray[1].viewController
pageViewController?.setViewControllers([vc!,nextVc!], direction: UIPageViewControllerNavigationDirection.forward, animated: false, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
extension ZHViewController : UIPageViewControllerDelegate,UIPageViewControllerDataSource{
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let subvc = viewController as! ZHSubViewController
var index = subvc.currentPage
index = index + 1
if index >= dataArray.count {
index = dataArray.count - 1
return nil
}
return dataArray[index].viewController
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let subvc = viewController as! ZHSubViewController
var index = subvc.currentPage
index = index - 1
if index < 0 {
index = 0
return nil
}
return dataArray[index].viewController
}
func pageViewController(_ pageViewController: UIPageViewController, spineLocationFor orientation: UIInterfaceOrientation) -> UIPageViewControllerSpineLocation {
if UIInterfaceOrientationIsLandscape(orientation) {
setDoublePage()
return UIPageViewControllerSpineLocation.mid
}
setOnePage()
return UIPageViewControllerSpineLocation.min
}
}
当前界面父类是UIPageViewController
import UIKit
class ZHPageViewController: UIPageViewController {
var dataArray : Array = []
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.white
prepareData()
// Do any additional setup after loading the view.
}
func prepareData(){
for i in 0 ..< 20 {
let page = BaseModel()
page.viewController = ZHSubViewController()
page.viewController?.currentPage = i
dataArray.append(page)
}
self.delegate = self
self.dataSource = self
if self.spineLocation == UIPageViewControllerSpineLocation.min {
setOnePage()
}
else
{
setDoublePage()
}
}
func setOnePage(){
self.isDoubleSided = false
let vc = dataArray[0].viewController
self.setViewControllers([vc!], direction: UIPageViewControllerNavigationDirection.forward, animated: false, completion: nil)
}
func setDoublePage(){
let vc = dataArray[0].viewController
let nextVc = dataArray[1].viewController
self.setViewControllers([vc!,nextVc!], direction: UIPageViewControllerNavigationDirection.forward, animated: false, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
extension ZHPageViewController : UIPageViewControllerDelegate,UIPageViewControllerDataSource{
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let subvc = viewController as! ZHSubViewController
var index = subvc.currentPage
index = index + 1
if index >= dataArray.count {
index = dataArray.count - 1
return nil
}
return dataArray[index].viewController
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let subvc = viewController as! ZHSubViewController
var index = subvc.currentPage
index = index - 1
if index < 0 {
index = 0
return nil
}
return dataArray[index].viewController
}
func pageViewController(_ pageViewController: UIPageViewController, spineLocationFor orientation: UIInterfaceOrientation) -> UIPageViewControllerSpineLocation {
if UIInterfaceOrientationIsLandscape(orientation) {
setDoublePage()
return UIPageViewControllerSpineLocation.mid
}
setOnePage()
return UIPageViewControllerSpineLocation.min
}
}
项目demo链接
PageViewControllerSpineLocation