首页 文章

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

提问于
浏览
3

我有一个带有滚动过渡样式的类 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
}
...

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

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

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

Update:

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

before completion : 1
before completion : 1
completed : 1

1 回答

  • 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)
            }
        }
    }
    

相关问题