Call both of After and Before Method in UIPageViewController when swim for forward in Swift 3 iOS

瘦欲@ 提交于 2019-12-13 12:23:49

问题


I made UIPageViewController with datasource array and it's works correctly. But when swiping to right for forwarding call both of After and Before methods.
My codes is here:

import UIKit

class MainPageViewController: UIPageViewController,UIPageViewControllerDataSource {


override func viewDidLoad() {
    super.viewDidLoad()

    self.dataSource = self
initUPageVC(idx:0,isAnimate:false,direction: UIPageViewControllerNavigationDirection.forward)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController?
{

    //PRIVIOUS
    let pageContent: MainPageContentViewController = viewController as! MainPageContentViewController

    var index = pageContent.index

    if ((index == 0) || (index == NSNotFound))
    {
        return nil
    }

    index -= 1;

    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "updateMenuBarItemSelectedNotif"), object: index)

    return getViewControllerAtIndex(index)
}

func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController?
{

    //NEXT
    let pageContent: MainPageContentViewController = viewController as! MainPageContentViewController

    print("now n",pageContent.index)

    var index = pageContent.index

    if (index == NSNotFound)
    {
        return nil;
    }

    index += 1;

    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "updateMenuBarItemSelectedNotif"), object: index)

    return getViewControllerAtIndex(index)
}
func getViewControllerAtIndex(_ index: Int) -> MainPageContentViewController
{
    // Create a new view controller and pass suitable data.

    let destinationVC = self.storyboard?.instantiateViewController(withIdentifier: "MainPageContentVCID") as! MainPageContentViewController

    destinationVC.index = index


    return destinationVC
}
func initUPageVC(idx:Int,isAnimate:Bool,direction:UIPageViewControllerNavigationDirection) {

    self.setViewControllers(
        [getViewControllerAtIndex(idx)],
        direction: direction,
        animated: isAnimate, completion: nil)

    let destinationVC = self.storyboard?.instantiateViewController(withIdentifier: "MainPageContentVCID") as! MainPageContentViewController

    destinationVC.index = idx

}  

And child vc code here:

import UIKit

class MainPageContentViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {

@IBOutlet var tableView: UITableView!
var dataSource : Array<Item>!
var index:Int = 0
var myStr:String!

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.register(UINib(nibName: "ItemCellNib", bundle: nil), forCellReuseIdentifier: "ItemCellIdentifier")

    prepareData()

}
//MARK: Table View
func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return dataSource.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCellIdentifier", for: indexPath) as! ItemTableViewCell

    let obj = dataSource[indexPath.row]

    cell.itemImage.image = UIImage(named:obj.imageName)




    cell.selectionStyle = UITableViewCellSelectionStyle.none

    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    let obj = dataSource[indexPath.row]
    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "itemHasClickedNotif"), object: obj)
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 197
}

func prepareData(){
    let obj0 = Item()
    let obj1 = Item()
    let obj2 = Item()
    let obj3 = Item()

    if index == 0 {

    obj0.ID = 0
    obj0.imageName = "dog"

    obj1.ID = 1
    obj1.imageName = "dog"

    obj2.ID = 2
    obj2.imageName = "dog"

    obj3.ID = 3
    obj3.imageName = "dog"

}else if index==1{

obj0.ID = 0
obj0.imageName = "cat"

obj1.ID = 1
obj1.imageName = "cat"

obj2.ID = 2
obj2.imageName = "cat"

obj3.ID = 3
obj3.imageName = "cat"
}else{
obj0.ID = 0
obj0.imageName = "lion"

obj1.ID = 1
obj1.imageName = "lion"


obj2.ID = 2
obj2.imageName = "lion"


obj3.ID = 3
obj3.imageName = "lion"

}


    dataSource = [obj0,obj1,obj2,obj3]

    tableView.setContentOffset(CGPoint.zero, animated: false)

    tableView.reloadData()
}
}  

Please help me to fix this problem Thank you.


回答1:


It isn't a problem with the page view controller. It's a problem with your assumptions about when viewControllerBefore and viewControllerAfter are called. Your assumptions seem reasonable, but they are wrong, as I will now explain.

You are assuming, for example, that when I am in, say, page 3 and I start to swipe to page 4, viewControllerAfter is called for page 3 so that you can submit page 4. That is not true. The scroll implementation of page view controller uses caching and lookahead to make scrolling faster. Thus, when you do what I just described, it may be that page 4 has already been cached, and now, when the scroll ends, the PVC will call viewControllerAfter for page 5, in order to pre-cache it in case you scroll again the same way later. Or, if this is the last page, it may be that nothing will be called at all.

This behavior means that you cannot make any assumptions about when viewControllerBefore and viewControllerAfter are called or for what page they are called. But your code, with your use of notifications in those methods, depends upon such assumptions — and those assumptions are wrong, and that is why your code isn't working. Everything seems to you to be off-by-one — because it is.

You might be able to solve the problem by relying for your signals instead on the delegate methods willTransitionTo and didFinishAnimating (see the docs on UIPageViewControllerDelegate).



来源:https://stackoverflow.com/questions/42031777/call-both-of-after-and-before-method-in-uipageviewcontroller-when-swim-for-forwa

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!