UIPageController:向前翻页然后向后翻页只会更新第一页

时间:2018-03-09 15:05:14

标签: ios swift uipageviewcontroller

我的课程SliderPgaeViewController: UIPageViewController具有滚动过渡样式,如下所示:

class SliderPgaeViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource, PlayerUpdatePageControllerDelegate {


var lastPendingIndex: Int = 0
var sliderPageDelegate: SliderPageDelegate? = nil
let playerManager = PlayerManager.getInstance()

override func viewDidLoad() {
    super.viewDidLoad()

    self.dataSource = self
    self.delegate = self
    setViewControllers([createViewController(index: playerManager.getCurrentIndex())!], direction: .forward, animated: true, completion: nil)
    lastPendingIndex = playerManager.getCurrentIndex()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

func presentationCount(for pageViewController: UIPageViewController) -> Int {
    return playerManager.getSongsCount()
}

func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
    if let vc = viewController as? PlayerImageViewController {
        if (vc.index == 0){
            return nil
        }
        return createViewController(index: vc.index! - 1)
    }
    return nil

}

func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
    if let vc = viewController as? PlayerImageViewController {
        if (vc.index == playerManager.getSongsCount() - 1){
            return nil
        }
        return createViewController(index: vc.index! + 1)
    }
    return nil
}


func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]){
    if let vc = pendingViewControllers[0] as? PlayerImageViewController {
        self.lastPendingIndex = vc.index!
    }
}

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool,previousViewControllers: [UIViewController],transitionCompleted completed: Bool) {
    print("before completion : \(self.lastPendingIndex)")
    if(completed){
        print("completed : \(self.lastPendingIndex)")
        if (viewControllers?.first as? PlayerImageViewController) != nil {
            sliderPageDelegate?.updateSong(index: self.lastPendingIndex, dir: 0)
        }
    }
}

private func createViewController(index i: Int) -> UIViewController?{
    let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PlayerImageController") as! PlayerImageViewController
    vc.index = i
    vc.image = playerManager.getSong(index: i).image
    return vc
}
...

我正在使用此页面控制器在音乐播放器中显示歌曲的缩略图。当用户翻页时,播放器通过调用sliderPageDelegate?.updateSong(index: self.lastPendingIndex, dir: 0)中的pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool,previousViewControllers: [UIViewController],transitionCompleted completed: Bool)来更改播放的歌曲

当我向前翻页然后向后翻页时,页面正确转动(先向前然后向后);但是,sliderPageDelegate?.updateSong(index: self.lastPendingIndex, dir: 0)仅在前进方向被调用。

因此,如果我们有歌曲列表(A, B, C, ...),我们目前正在歌曲A。当用户向前滑动时,缩略图将更改为B's缩略图,并且播放器会将歌曲更新为B。但是,如果向前滑动后面会快速向后滑动,则缩略图会更改为A,但歌曲仍为B

更新

如果Aindex = 0Bindex = 1,则快速移动A->B->A会打印以下内容:

before completion : 1
before completion : 1
completed : 1

1 个答案:

答案 0 :(得分:0)

我在您的代码中添加了PageControllerDelegate并介绍了两种新方法。然后在UIPageViewController类中实现这些代理,然后在PlayerImageViewController类中调用viewWillAppearviewWillDisappear中的两种方法。现在删除didFinishAnimation方法并将该代码写入viewControllerIsBeingDisplay

有关更深入的知识,请查看此代码。

class PlayerImageViewController: UIViewController {
    var index: Int?
    var image: UIImage?
    weak var delegate: PageControllerDelegate?


    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        if let del = self.delegate {
            del.viewControllerIsBeingHide(self)
        }
    }
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        if let del = self.delegate {
            del.viewControllerIsBeingDisplay(self)
        }
    }
}
protocol SliderPageDelegate {
    func updateSong(index: Int, dir: Int)
}
protocol PageControllerDelegate {
    func viewControllerIsBeingHide(_ viewController: PlayerImageViewController)
    func viewControllerIsBeingDisplay(_ viewController: PlayerImageViewController)
}
class SliderPgaeViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource, PageControllerDelegate {


    var lastPendingIndex: Int = 0
    var sliderPageDelegate: SliderPageDelegate? = nil

    override func viewDidLoad() {
        super.viewDidLoad()

        self.dataSource = self
        self.delegate = self
        setViewControllers([createViewController(index: playerManager.getCurrentIndex())!], direction: .forward, animated: true, completion: nil)
        lastPendingIndex = playerManager.getCurrentIndex()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    func presentationCount(for pageViewController: UIPageViewController) -> Int {
        return playerManager.getSongsCount()
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        if let vc = viewController as? PlayerImageViewController {
            if (vc.index == 0){
                return nil
            }
            return createViewController(index: vc.index! - 1)
        }
        return nil

    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        if let vc = viewController as? PlayerImageViewController {
            if (vc.index == playerManager.getSongsCount() - 1){
                return nil
            }
            return createViewController(index: vc.index! + 1)
        }
        return nil
    }


    func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]){
        if let vc = pendingViewControllers[0] as? PlayerImageViewController {
            self.lastPendingIndex = vc.index!
        }
    }


    private func createViewController(index i: Int) -> UIViewController?{
        let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PlayerImageController") as! PlayerImageViewController
        vc.index = i
        vc.delegate = self
//        vc.image = playerManager.getSong(index: i).image //Commented becoz i do not have this file
        return vc
    }
    var previousVCIndex = 0

    func viewControllerIsBeingHide(_ viewController: PlayerImageViewController) {
        previousVCIndex = viewController.index!
    }
    func viewControllerIsBeingDisplay(_ viewController: PlayerImageViewController) {
        if let del = sliderPageDelegate {
            del.updateSong(index: previousVCIndex, dir: 0)
        }
    }
}