UIPageViewControllerSpineLocation委托方法未触发

时间:2012-08-10 03:42:49

标签: objective-c ios5 uiinterfaceorientation uipageviewcontroller

这一天的主要问题是: - (

我有一个UIPageViewController实例似乎没有触发委托方法:

-(UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController
                  spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation

我已经尝试了各种显示UIPageViewController的方法,并且已经确定了一种似乎正常工作的程序方法(而不是故事板),但有一个例外......当将iPad旋转到横向时,脊柱不会按预期出现在中点。我根本无法找出为什么委托方法不被调用。

代码说明(例如简化)

考虑以下三个类:

  • RootViewController - 在应用启动时加载
  • PageViewController - 在用户启动时由RootViewController加载
  • PageContentViewController - 在需要页面时由PageViewController加载

相当不言自明。 RootViewController在启动时由应用程序加载。当用户在该视图控制器的视图中点击图像时(想想杂志封面打开杂志),它会按如下方式启动PageViewController:

PageViewController *pvc = [[PageViewController alloc] initWithNibName:@"PageView" 
                                           bundle:[NSBundle mainBundle]];
pvc.view.frame = self.view.bounds;
[self.view addSubview:pvc.view];

在实际的应用程序中有动画等使转换都很好,但基本上是加载了PageViewController的视图并全屏显示。

PageViewController

这是主力(仅显示相关方法)。我尝试过来自Google无限世界的各种例子,并直接从Apple文档编写......

@interface PageViewController : UIViewController <UIPageViewControllerDelegate, UIPageViewControllerDataSource>

@property (nonatomic, strong) UIPageViewController *pageViewController;
@property (nonatomic, strong) NSMutableArray *modelArray;

@end


@implementation TXCategoryController

-(void)viewDidLoad 
{

    [super viewDidLoad];

    // Simple model for demo
    self.modelArray = [NSMutableArray alloc] init];

    for (int i=1; i<=20; i++)
        [self.modelArray addObject:[NSString stringWithFormat:@"Page: %d", i]];

    self.pageViewController = [[UIPageViewController alloc] 
               initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl
                 navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];

    self.pageViewController.delegate = self;
    self.pageViewController.dataSource = self;

    PageContentViewController *startupVC = [[PageContentViewController alloc] initWithNibName:@"PageContent" bundle:nil];

    startupVC.pageLabel = [self.modelArray objectAtIndex:0];

    [self.pageViewController setViewControllers:[NSArray arrayWithObject:startupVC]
                                      direction:UIPageViewControllerNavigationDirectionForward
                                       animated:NO
                                     completion:nil];

    [self addChildViewController:self.pageViewController];
    [self.view addSubview:self.pageViewController.view];
    [self.pageViewController didMoveToParentViewController:self];
    self.pageViewController.view.frame = self.view.bounds;
    self.view.gestureRecognizers = self.pageViewController.gestureRecognizers;

}

-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController
  viewControllerBeforeViewController:(UIViewController *)viewController
{
    // Relevant code to add another view...
}

-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController
   viewControllerAfterViewController:(UIViewController *)viewController
{
    // Relevant code to add another view...
}

-(UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController
                  spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation

{
    // Setting a break point in here - never gets called

    if (UIInterfaceOrientationIsPortrait(orientation))
    {
        // Relevant code to create view...
        return UIPageViewControllerSpineLocationMin;
    }

    // Relevant code to create 2 views for side-by-side display and
    // set those views using self.pageViewController setViewControllers:

    return UIPageViewControllerSpineLocationMid
}

@end

如前所述,这一切都非常有效。显示PageViewController的视图。我可以在纵向和横向上左右滑动页面,并显示相应的页码。但是,我从来没有在横向视图中看到两页并排。在spineLocationForInterfaceOrientation委托方法中设置断点永远不会被调用。

对于如何调试/解决问题,我已经烧掉了这个令人头疼的问题。它几乎像UIPageViewController没有响应设备的方向更改,因此不会触发委托方法。但是,视图会正确调整大小(但这可能只是处理该更改的UIView自动调整掩码)。

如果我用这个代码(以及适当的XIb等)创建一个全新的项目,它的工作非常好。因此,在我的实际项目中的某个地方引起了这种情况。我不知道在哪里继续寻找。

像往常一样,非常感谢任何和所有的帮助。

旁注

我想添加标签&#39; uipageviewcontrollerspinelocation&#39;但是因为它太长而我没有足够的声誉(需要1500个),因此无法实现。我认为这是苹果公司在Stackoverflow中避免使用某些标签的一种狡猾的伎俩...; - )

1 个答案:

答案 0 :(得分:2)

终于找到了问题。它的症状有点红鲱鱼,但是相关的一样。

shouldAutorotateToInterfaceOrientation:方法中设置一个断点是一个自然的测试,看看UIViewController是否甚至得到了一个旋转通知。在这个问题上,并没有让我看到Apple的技术问答:http://developer.apple.com/library/ios/#qa/qa1688/_index.html

最相关的一点是:

The view controller's UIView property is embedded inside UIWindow but alongside an additional view controller.

不幸的是,Apple的传统文档风格并没有提供答案,仅仅是对问题的确认。但Stack Overflow的答案产生了下一个线索:

Animate change of view controllers without using navigation controller stack, subviews or modal controllers?

虽然我的RootViewController正在加载PageViewController,但我把它作为主视图的子视图。这意味着我有两个UIViewController,其中只有父级会响应更改。

让PageViewController监听方向更改(从而触发相关的spine委托方法)的解决方案是删除addSubview:,而是从RootViewController呈现视图控制器:

[self presentViewController:pac animated:YES completion:NULL];

完成后,方向更改被拾取并且PageViewController正在触发脊椎位置的委托方法。只考虑一个小细节。如果视图是以横向方式启动的,则视图仍会显示纵向,直到旋转为纵向并返回到横向。

通过编辑viewDidLoad可以轻松调整,如下所示:

PageContentViewController *page1 = [[PageContentViewController alloc] initWithNibName:@"PageContent" bundle:nil];

NSDictionary *pageViewOptions = nil;
NSMutableArray *pagesArray = [NSMutableArray array];

if (IS_IPAD && UIInterfaceOrientationIsLandscape(self.interfaceOrientation))
{
    pageViewOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:UIPageViewControllerSpineLocationMid]
                                                  forKey:UIPageViewControllerOptionSpineLocationKey];

    PageContentViewController *page2 = [[PageContentViewController alloc] initWithNibName:@"PageContent" bundle:nil];

    [pagesArray addObject:page1];
    [pagesArray addObject:page2];
}
else
{
    [pagesArray addObject:page1];
}


self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl
                                                          navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal
                                                                        options:pageViewOptions];
self.pageViewController.delegate = self;

[self.pageViewController setViewControllers:pagesArray
                                  direction:UIPageViewControllerNavigationDirectionForward
                                   animated:NO
                                 completion:NULL];

完成工作并解决问题。