8

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

具有 3 个视图的示例工作流:

  1. 呈现的第一个视图
  2. 向右滑动
  3. 第二个视图闪烁进出
  4. 向右滑动
  5. 呈现的第二个视图
  6. 向右滑动
  7. 呈现的第三个视图
  8. 向左滑动
  9. 第二个视图闪烁进出
  10. 向左滑动
  11. 呈现的第二个视图

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

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

然后,当我再次滑动 GetNextViewController 时,它会被适当地调用并显示视图。

我的问题是,显然,第二个视图应该显示没有闪烁。我尝试了各种各样的事情,但没有任何成果。

更新

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

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;
        }
    }
}
4

1 回答 1

9

iOS 会调用 GetPreviousViewController 和 GetNextViewController 两次:第一次调用当前控制器,第二次调用当前控制器的后空翻。

你应该这样做

当前=当前。上一个;

仅在第一次通话时。

检查 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;
    }
于 2013-04-23T03:42:25.433 回答