在Swift 3 iOS中向前游泳时,请在UIPageViewController中同时调用After和Before方法 [英] Call both of After and Before Method in UIPageViewController when swim for forward in Swift 3 iOS

查看:72
本文介绍了在Swift 3 iOS中向前游泳时,请在UIPageViewController中同时调用After和Before方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用数据源数组制作了UIPageViewController,它可以正常工作.但是向右滑动以转发时,请同时调用After和Before方法.
我的代码在这里:

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

}  

此处有子vc代码:

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.

推荐答案

这不是页面视图控制器的问题.关于何时调用viewControllerBeforeviewControllerAfter的假设存在问题.您的假设似乎是合理的,但它们是错误的,正如我现在要解释的那样.

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.

例如,您假设当我进入第3页并且开始滑动到第4页时,第3页会调用viewControllerAfter,以便您可以提交第4页.不是.页面视图控制器的滚动实现使用缓存 lookahead 来加快滚动速度.因此,当您执行我刚刚描述的操作时,可能是第4页已经被缓存,现在,当滚动结束时,PVC将为第5页调用viewControllerAfter,以便预缓存它,以防您以后以相同的方式再次滚动.或者,如果这是最后一页,则可能根本不会调用任何内容.

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.

此行为意味着您不能对何时调用 viewControllerBeforeviewControllerAfter调用哪个页面做任何假设.但是您的代码以及在这些方法中使用通知的代码取决于这些假设-这些假设是错误的,这就是为什么您的代码无法正常工作的原因.在您看来,所有事物都是一一对应的-因为它是.

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.

您也许可以依靠信号来解决问题,而不是依靠 delegate 方法willTransitionTodidFinishAnimating(请参阅UIPageViewControllerDelegate上的文档).

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).

这篇关于在Swift 3 iOS中向前游泳时,请在UIPageViewController中同时调用After和Before方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆