我在iOS应用中使用UIPageViewController
来在视图控制器之间进行切换。每个视图控制器都包含SKView
,而不包含任何其他内容。
页面卷曲效果非常好,正如您在附带的gif中看到的那样。只有在动画结束时,屏幕边缘才会出现这种奇怪的阴影。
以下是相关的源代码,如下所示:
这是ModelController
import UIKit
class ModelController: NSObject, UIPageViewControllerDataSource {
var pageIsAnimating=false
let rootViewController:RootViewController!
var nextViewController:BookPageViewController?
var prevViewController:BookPageViewController?
var storyboard:UIStoryboard
init(rootViewController:RootViewController) {
self.rootViewController=rootViewController
let storyboardName = "Main";
storyboard = UIStoryboard(name: storyboardName, bundle: nil)
super.init()
nextViewController = viewControllerAtIndex(1)
}
func preloadViewControllers(index: Int, forward:Bool, oldViewController: UIViewController)
{
if(index+1<Static.bookPages.count)
{
print("preloading next: "+(index+1).description)
if(!forward)
{
print("taking oldviewcontroller")
nextViewController = oldViewController as? BookPageViewController
}
else
{
nextViewController = viewControllerAtIndex(index+1)
}
}
if(index-1 >= 0)
{
print("preloading prev: "+(index-1).description)
if(forward)
{
print("taking oldviewcontroller")
prevViewController = oldViewController as? BookPageViewController
}
else
{
prevViewController = viewControllerAtIndex(index-1)
}
print("after preloading prev")
}
}
func viewControllerAtIndex(index: Int) -> BookPageViewController
{
let viewController = storyboard.instantiateViewControllerWithIdentifier("BookPageViewController") as! BookPageViewController
viewController.bookPage = ModelController.Static.boboStory.bookPages[index]
viewController.index=index
viewController.rootViewController=rootViewController
viewController.loadResources()
return viewController
}
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
print("viewControllerBefore")
let currentIndex=(viewController as! BookPageViewController).index
if pageIsAnimating {
return nil
}
if (currentIndex == 0) {
return nil
}
let returnViewController=prevViewController
prevViewController=nil
return returnViewController
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
print("viewControllerAfter")
let currentIndex=(viewController as! BookPageViewController).index
if pageIsAnimating {
return nil
}
if currentIndex == ModelController.Static.boboStory.bookPages.count-1
{
return nil
}
let returnViewController=nextViewController
nextViewController=nil
return returnViewController
}
}
这是RootViewController
:
import UIKit
class RootViewController: UIViewController, UIPageViewControllerDelegate {
var pageViewController: UIPageViewController?
var recordings:[Int:Record]!
var currentRecord=0
var nextIndex:Int = 0
var currentIndex:Int = 0
override func viewWillAppear(animated: Bool) {
self.navigationController?.setNavigationBarHidden(true, animated: animated);
setScrollEnabled(true)
super.viewWillAppear(animated);
}
func setViewControllers()
{
let startingViewController: BookPageViewController = self.modelController.viewControllerAtIndex(0)
let viewControllers: [UIViewController] = [startingViewController]
self.pageViewController!.setViewControllers(viewControllers as [UIViewController], direction: .Forward, animated: false, completion: {done in })
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "RootToParentModeViewController") {
let parentModeViewController = segue.destinationViewController as! ParentModeViewController
parentModeViewController.rootViewController=self
}
}
override func viewDidLoad() {
super.viewDidLoad()
UIApplication.sharedApplication().setStatusBarHidden(false, withAnimation: UIStatusBarAnimation.None)
recordings=DataManager.sharedInstance.getRecordings()
// Do any additional setup after loading the view, typically from a nib.
// Configure the page view controller and add it as a child view controller.
self.pageViewController = UIPageViewController(transitionStyle: .PageCurl, navigationOrientation: .Horizontal, options: nil)
self.pageViewController!.delegate = self
setViewControllers()
self.pageViewController!.dataSource = self.modelController
self.addChildViewController(self.pageViewController!)
self.view.addSubview(self.pageViewController!.view)
self.pageViewController!.view.frame=self.view.bounds
self.pageViewController!.didMoveToParentViewController(self)
// Add the page view controller's gesture recognizers to the book view controller's view so that the gestures are started more easily.
//self.view.gestureRecognizers = self.pageViewController!.gestureRecognizers
self.view.gestureRecognizers = self.pageViewController!.gestureRecognizers
// Find the tap gesture recognizer so we can remove it!
for recognizer in self.pageViewController!.gestureRecognizers {
if ( recognizer is UITapGestureRecognizer ) {
self.view.removeGestureRecognizer(recognizer)
self.pageViewController?.view.removeGestureRecognizer(recognizer)
break;
}
}
}
func reloadRecordings()
{
recordings=DataManager.sharedInstance.getRecordings()
setViewControllers()
}
func setScrollEnabled(enabled:Bool) {
for recognizer in self.pageViewController!.gestureRecognizers {
if(recognizer is UIPanGestureRecognizer)
{
(recognizer as! UIPanGestureRecognizer).enabled=enabled
}
}
}
func getCurrentRecord() -> Int
{
return currentRecord
}
func getCurrentLanguage() -> Record.RecordLanguage
{
return recordings[currentRecord]!.language
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
var modelController: ModelController {
// Return the model controller object, creating it if necessary.
// In more complex implementations, the model controller may be passed to the view controller.
if _modelController == nil {
_modelController = ModelController(rootViewController: self)
}
return _modelController!
}
var _modelController: ModelController? = nil
// MARK: - UIPageViewController delegate methods
func pageViewController(pageViewController: UIPageViewController, spineLocationForInterfaceOrientation orientation: UIInterfaceOrientation) -> UIPageViewControllerSpineLocation {
return .Min
}
func pageViewController(pageViewController: UIPageViewController, willTransitionToViewControllers pendingViewControllers: [UIViewController]) {
print("willtransitiontoviewcontroller")
self.modelController.pageIsAnimating=true
self.nextIndex=(pendingViewControllers.first as! BookPageViewController).index!
}
func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if(finished)
{
self.modelController.pageIsAnimating=false
}
if (completed){
var forward=false
if(self.currentIndex<self.nextIndex)
{
forward=true
}
self.currentIndex=self.nextIndex
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), {
self.modelController.preloadViewControllers(self.currentIndex, forward: forward, oldViewController: previousViewControllers[0])
});
}// Turn is either finished or aborted
print("didFinishAnimating")
}
override func prefersStatusBarHidden() -> Bool {
return true
}
}
这是PageViewController
:
import UIKit
import SpriteKit
class BookPageViewController: UIViewController
{
var bookPage:BookPage?
var index:Int?
var rootViewController:RootViewController?
@IBOutlet var mainView: SKView!
var scene:BookPageSKScene?
var storyImageSpriteNode:SKSpriteNode?
var flagSpriteNodes=[Int:SKSpriteNode]()
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func loadResources()
{
print("loadResources: "+index!.description)
storyImageSpriteNode = SKSpriteNode(imageNamed: bookPage!.pageImage)
for (id, record) in rootViewController!.recordings {
flagSpriteNodes[id]=SKSpriteNode(texture: SKTexture(image: record.getRecordImage()!))
}
}
override func viewDidLoad() {
super.viewDidLoad()
print("viewdidload: "+index!.description)
scene=BookPageSKScene(bookPage: bookPage!, size: self.mainView.frame.size, parentViewController: rootViewController!, storyImageSpriteNode: storyImageSpriteNode!, flagSpriteNodes: flagSpriteNodes);
/* Set the scale mode to scale to fit the window */
scene!.scaleMode = .ResizeFill
scene!.backgroundColor = SKColor.whiteColor();
// Configure the view.
mainView.showsFPS = false
mainView.showsNodeCount = false
/* Sprite Kit applies additional optimizations to improve rendering performance */
mainView.ignoresSiblingOrder = true
mainView.presentScene(scene)
}
override func shouldAutorotate() -> Bool {
return true
}
override func prefersStatusBarHidden() -> Bool {
return true;
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Release any cached data, images, etc that aren't in use.
}
}
答案 0 :(得分:0)
在UIPageViewController动画结束时页面卷曲动画挂起的一个可能原因可能是:
如果你在UIViewControllers的viewDidLoad()函数中进行大量计算,就像在viewDidLoad()函数中将数据传递给UIWebView或将html字符串传递给UITextView / UILabel一样。将那些繁重的计算移动到viewDidAppear()功能。也许这可以帮到你。快乐的编码!