页面卷曲过渡在动画结束时挂起的原因是什么?

时间:2015-09-20 08:39:26

标签: ios swift curl uipageviewcontroller

我在iOS应用中使用UIPageViewController来在视图控制器之间进行切换。每个视图控制器都包含SKView,而不包含任何其他内容。

页面卷曲效果非常好,正如您在附带的gif中看到的那样。只有在动画结束时,屏幕边缘才会出现这种奇怪的阴影。

Gif of Page Curl

Shadow at the end

以下是相关的源代码,如下所示:

这是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.
    }



}

1 个答案:

答案 0 :(得分:0)

在UIPageViewController动画结束时页面卷曲动画挂起的一个可能原因可能是:

如果你在UIViewControllers的viewDidLoad()函数中进行大量计算,就像在viewDidLoad()函数中将数据传递给UIWebView或将html字符串传递给UITextView / UILabel一样。将那些繁重的计算移动到viewDidAppear()功能。也许这可以帮到你。快乐的编码!