UIPageViewController在以编程方式设置时显示空白视图控制器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UIPageViewController在以编程方式设置时显示空白视图控制器相关的知识,希望对你有一定的参考价值。
我有一个UIPageViewController
,其中我实现了一个缓存机制。实际上我有一个视图控制器池,当UIPageViewControllerDataSource
中请求下一个或上一个视图控制器时,我尝试尽可能多地重用它们。因此,当数据源请求上一页或下一页时,我首先检查该页是否已经显示并返回相应的视图控制器。
这一切都可以使用默认的滑动手势和更改页面的内部方法。现在我需要禁用滑动手势,所以我没有设置数据源,相反,我有两个按钮可以转到上一页和下一页,并使用setViewControllers(_:direction:animated:completion:)
以编程方式更改页面。它总是在同一个方向上工作正常,但是一旦我改变它,所以我使用缓存的视图控制器,它显示一个空白页面。
代码与之前完全相同,如果不是以编程方式设置视图控制器。我已尝试过有或没有动画,结果是一样的,如果我删除缓存它也很好。我的问题是,我忘了什么吗?当分配数据源时,UIPageViewController
在内部执行某些操作吗?
编辑
这是代码的简化版本。这是一个Xamarin项目,但我认为这是可以理解的
public class MyPageViewController : AbstractPageViewController
{
const int CacheCapacity = 5;
public int initialItemId { get; set; }
public List<int> ItemIds { get; set; }
readonly List<ChildViewController> viewControllerCache = new List<ChildViewController>(CacheCapacity + 1);
public override void ViewDidLoad()
{
base.ViewDidLoad();
DataSource = null;
var vc = GetDocumentViewController(initialItemId);
SetViewControllers(new[] { vc }, UIPageViewControllerNavigationDirection.Forward, false, null);
var nextButtonItem = new UIBarButtonItem
{
Enabled = true
};
var previousButtonItem = new UIBarButtonItem
{
Enabled = true
};
nextButtonItem.Clicked += NextDocumentButton_Clicked;
previousButtonItem.Clicked += PreviousDocumentButton_Clicked;
var rightButtons = new UIBarButtonItem[2];
rightButtons[0] = nextButtonItem;
rightButtons[1] = previousButtonItem;
NavigationItem.SetRightBarButtonItems(rightButtons, false);
}
private void PreviousDocumentButton_Clicked(object sender, EventArgs e)
{
var referenceVc = (ChildViewController)ViewControllers.FirstOrDefault();
var referenceId = referenceVc.ItemId;
var index = ItemIds.FindIndex(dp => dp.Id == referenceId);
if (index < 1)
return;
var previousDocumentId = ItemIds[index - 1];
var vc = GetDocumentViewController(previousDocumentId);
SetViewControllers(new[] { vc }, UIPageViewControllerNavigationDirection.Reverse, false, null);
}
private void NextDocumentButton_Clicked(object sender, EventArgs e)
{
var referenceVc = (ChildViewController)ViewControllers.FirstOrDefault();
var referenceId = referenceVc.ItemId;
var index = ItemIds.FindIndex(dp => dp.Id == referenceId);
if (index < 0 || index >= ItemIds.Count)
return;
var nextDocumentId = ItemIds[index + 1];
var vc = GetDocumentViewController(nextDocumentId);
SetViewControllers(new[] { vc }, UIPageViewControllerNavigationDirection.Forward, false, null);
}
ChildViewController GetDocumentViewController(int ItemId)
{
var cachedViewController = viewControllerCache.FirstOrDefault(dvc => dvc.ItemId == ItemId);
if (cachedViewController != null)
return cachedViewController;
var vc = new ChildViewController();
vc.SetData(itemId);
viewControllerCache.Add(vc);
if (viewControllerCache.Count > CacheCapacity)
{
viewControllerCache[0].RecycleIfNeeded();
viewControllerCache.RemoveAt(0);
}
return vc;
}
}
事实证明,这是由于我的代码中实现的回收机制。
特别是,在ViewDidDisappear
上强制回收视图控制器的内容。我已经在这种情况下禁用它,然后它可以正常工作。这也意味着当UIPageViewController
具有数据源并且直接管理子视图控制器时,通过滑动更改页面时不会调用ViewDidDisappear
。
以上是关于UIPageViewController在以编程方式设置时显示空白视图控制器的主要内容,如果未能解决你的问题,请参考以下文章
以编程方式平滑滚动 UIPageViewController
UIPageViewController 内的 UITableViewController,如何防止对角拖动
iOS Swift:UIPageViewController - 以编程方式翻页
以编程方式将 UIPageViewController 过渡样式设置为滚动