0

主要头饼刷整天就这一个:-(UIPageViewControllerSpineLocation委托方法不点火

我有没有出现被解雇的委托方法的UIPageViewController的一个实例:

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

我已经尝试过显示UIPageViewController的各种方法,并且已经解决了似乎正在正常工作的程序化方法(与Storyboard相反),但有一个例外......当旋转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

这是重负荷(仅示出了相关的方法)。我从谷歌的无限世界尝试各种实例,并直接从苹果的文档写的...

@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's等)创建一个全新的项目,它工作得很好。所以在我的实际项目中的某个地方造成了这种情况。我不知道在哪里继续寻找。

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

旁注

我想添加标签“uipageviewcontrollerspinelocation”,但不能因为它太长时间,我没有足够的声誉(需要1500)。我认为这是苹果的一个迂回策略,以避免Stackoverflow中的某些标签... ;-)

+0

您是否将过渡样式设置为UIPageViewControllerTransitionStylePageCurl? – rdelmar 2012-08-10 03:58:57

+0

@rdelmar - 我喜欢。我在文档中注意到它说如果你忽略这个关键设置,你可以吻别两页传播...... – Hooligancat 2012-08-10 04:19:15

+0

如果你在一个新项目中工作,你可以区分XIB文件,看看是否有设置你不小心绊倒了IB – 2012-08-10 05:44:16

回答

2

终于找到了问题。它的症状是一种红鲱鱼,但也是相同的。

shouldAutorotateToInterfaceOrientation:方法中放置一个断点是一个自然的测试,以查看UIViewController是否获得了旋转通知。这不是害得我苹果对问题技术答疑&答: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. 

不幸的是,苹果公司在其传统风格的文件,不提供答案,仅仅是问题的确认。但是在堆栈溢出的答案产生下一个线索:

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

虽然我的RootViewController的是加载PageViewController,我在做它作为一个子视图到主视图。这意味着我有两个UIViewController,其中只有父母会响应更改。

的溶液,以获得PageViewController听取向的变化(从而触发相关的脊柱委托方法)中的溶液,以除去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]; 

工作完成,问题就解决了。

+0

只为有人来到这里,我想补充说,你的发现与儿童视图控制器有关。 UIPageViewController是视图控制器遏制的一个很好的例子,并且利用了其中的大部分,主要是方向改变事件被转发给子控制器。 – 2013-05-14 15:26:05