这一天的主要问题是: - (
我有一个UIPageViewController实例似乎没有触发委托方法:
-(UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController
spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation
我已经尝试了各种显示UIPageViewController的方法,并且已经确定了一种似乎正常工作的程序方法(而不是故事板),但有一个例外......当将iPad旋转到横向时,脊柱不会按预期出现在中点。我根本无法找出为什么委托方法不被调用。
代码说明(例如简化)
考虑以下三个类:
相当不言自明。 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中避免使用某些标签的一种狡猾的伎俩...; - )
答案 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的答案产生了下一个线索:
虽然我的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];
完成工作并解决问题。