ios - UIPageViewController 第二个 View 变为空白

标签 ios xamarin.ios uipageviewcontroller

在我的应用程序中使用 UIPageViewController 时,我遇到了一些非常奇怪的行为。在第一次滑动到下一个 View 或滑动方向发生变化时(即在列表末尾并返回),生成的 View 是空白的,我需要再次滑动相同的方向才能显示适当的 View 。

具有 3 个 View 的示例工作流:

  1. 提出第一个观点
  2. 向右滑动
  3. 第二个 View 闪烁进进出出
  4. 向右滑动
  5. 提出第二个观点
  6. 向右滑动
  7. 呈现第三种观点
  8. 向左滑动
  9. 第二个 View 闪烁进进出出
  10. 向左滑动
  11. 提出第二个观点

当闪烁发生时(上面的 2 和 3),我通过日志记录注意到,事件的顺序如下:

  1. 调用 GetNextViewController
  2. 调用 GetPreviousViewController
  3. 调用 GetNextViewController

然后,当我再次滑动时,会适本地调用 GetNextViewController 并显示 View 。

显然,我的问题是,第二个 View 应该在不闪烁的情况下显示。我尝试了各种方法,但没有任何成果。

更新

这是一个重现问题的示例单 Controller 应用程序:

using System;
using System.Drawing;

using MonoTouch.Foundation;
using MonoTouch.UIKit;
using System.Collections.Generic;

namespace TestPageView
{
    public partial class TestPageViewViewController : UIViewController
    {
        public TestPageViewViewController () : base ("TestPageViewViewController", null)
        {
        }

        public override void DidReceiveMemoryWarning ()
        {
            // Releases the view if it doesn't have a superview.
            base.DidReceiveMemoryWarning ();

            // Release any cached data, images, etc that aren't in use.
        }

        public override void ViewDidLoad ()
        {
            base.ViewDidLoad ();

            var controllers = new List<UIViewController>
            {
                new TestViewController(View, 1),
                new TestViewController(View, 2),
                new TestViewController(View, 3),
                new TestViewController(View, 4)
            };

            var _pageViewController = new UIPageViewController(UIPageViewControllerTransitionStyle.Scroll, UIPageViewControllerNavigationOrientation.Horizontal);
            var dataSource = new ViewDataSource(controllers);
            _pageViewController.DataSource = dataSource;
            //ViewDataSource has an indexer that returns it's controllers
            _pageViewController.SetViewControllers(new[] { controllers[0] }, UIPageViewControllerNavigationDirection.Forward, false, null);
            View.AddSubview(_pageViewController.View);
        }

        public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation)
        {
            // Return true for supported orientations
            return (toInterfaceOrientation != UIInterfaceOrientation.PortraitUpsideDown);
        }
    }

    public class TestViewController : UIViewController
    {
        private readonly UIView _parent;
        private readonly int _number;
        public TestViewController(UIView parent, int number)
        {
            _parent = parent;
            _number = number;
        }

        public override void ViewDidLoad ()
        {
            base.ViewDidLoad ();

            var textView = new UITextView(_parent.Bounds);
            textView.TextAlignment = UITextAlignment.Center;
            textView.AttributedText = new NSAttributedString(_number.ToString(), UIFont.BoldSystemFontOfSize(18));
            View.Add(textView);
        }
    }

    public class ViewDataSource : UIPageViewControllerDataSource
    {
        private LinkedListNode<UIViewController> current;

        public ViewDataSource(IEnumerable<UIViewController> controllers)
        {
            var controllerLiist = new LinkedList<UIViewController>(controllers);
            current = controllerLiist.First;
        }

        public override UIViewController GetPreviousViewController(UIPageViewController pageViewController, UIViewController referenceViewController)
        {
            if(current.Previous == null){
                Console.WriteLine("returning previous nothing");
                return null;
            }
            Console.WriteLine("returning previous something");
            current = current.Previous;
            return current.Value;
        }

        public override UIViewController GetNextViewController(UIPageViewController pageViewController, UIViewController referenceViewController)
        {
            if(current.Next == null){
                Console.WriteLine("returning next nothing");
                return null;
            }
            Console.WriteLine("returning next something");
            current = current.Next;
            return current.Value;
        }
    }
}

最佳答案

iOS 将调用 GetPreviousViewController 和 GetNextViewController 两次:第一次针对当前 Controller ,第二次针对当前 Controller 的后空翻。

你应该这样做

current = current.Previous;

仅在第一次调用时。

检查 referenceViewController 来做到这一点:

public override UIViewController GetPreviousViewController (UIPageViewController pageViewController, UIViewController referenceViewController)
    {
        var __c = Pages.Find(referenceViewController);

        if (__c.Previous != null)
            return __c.Previous.Value;
        else
            return null;
    }
    public override UIViewController GetNextViewController (UIPageViewController pageViewController, UIViewController referenceViewController)
    {
        var __c = Pages.Find(referenceViewController);

        if (__c.Next != null)
            return __c.Next.Value;
        else
            return null;
    }

关于ios - UIPageViewController 第二个 View 变为空白,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16022576/

相关文章:

ios - Xamarin.iOS 应用程序启动崩溃,控制台中没有崩溃日志和失败消息

.net - 在 Apple 的 VerifyReceipt 上继续获取 21002 'java.lang.NullPointerException'

ios - 如何使用自动布局在 UIPageViewController 中定位 subview ?

ios - 在 UIPageViewControllers 中预加载所有 UIViewControllers (Swift)

ios - Swift - 如何从一个 View Controller 转移到另一个?

android - 是否有跨平台框架可以访问 Android、iOS 和 Windows Phone 的短信内容?

iPhone 如果我有 4 张静止图像,什么样的动画会模仿旋转对象?

ios - 核心音频 : How to play MIDI MusicSequence by MusicPlayer while AUGraph is deprecated?

xamarin.ios - 相当于 UIWebView 选择器 webView :shouldStartLoadWithRequest:navigationType: in MonoTouch

ios - UIPageViewController 有条件地转到下一页