问题描述
我用数据源数组制作了 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.
推荐答案
不是页面视图控制器的问题.您对何时调用 viewControllerBefore
和 viewControllerAfter
的假设存在问题.你的假设似乎是合理的,但它们是错误的,我现在将解释.
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 将调用 viewControllerAfter
页面5,为了预先缓存它,以防您以后再次以相同的方式滚动.或者,如果这是最后一页,则可能根本不会调用任何内容.
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.
这种行为意味着您不能对 何时 viewControllerBefore
和 viewControllerAfter
被调用或 对于什么页面 他们被称为.但是你的代码,以及你在这些方法中使用通知,依赖于这样的假设——这些假设是错误的,这就是你的代码不起作用的原因.在你看来,一切似乎都是不一样的——因为它是.
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 方法 willTransitionTo
和 didFinishAnimating
来解决问题(请参阅文档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 方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!