强制隐藏详细视图后未调用 UISplitViewController willHideViewController/willShowViewController
我有一个 iPad 应用程序,它使用 UISplitViewController 作为根控制器,我已经设置了委托,并且我正在使用 UINavigationController 作为 DetailView,它似乎工作正常。
当特定视图控制器显示在 DetailView 部分中时,我希望 MasterViewContoller 始终隐藏(在所有旋转中)。我可以使用 UISplitViewController 委托上的 shouldHideViewController 方法来执行此操作。
但是,如果我这样做,那么当我将 DetailView 部分中的 ViewController 更改为另一个时,会显示 MasterView,但委托中不会调用 willHideViewController/willShowViewController 。
如果我旋转设备并旋转回来,它们就会被调用并且它会按预期工作,但直到设备旋转并旋转回原始方向后才会调用它们。
这会导致在显示 MasterView 后第一次旋转时不显示弹出按钮。
- (void)splitViewController:(UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItem forPopoverController:(UIPopoverController*)pc {
// Keep references to the popover controller and the popover button, and tell the detail view controller to show the button.
barButtonItem.title = @"Survey Sections";
self.popoverController = pc;
self.rootPopoverButtonItem = barButtonItem;
UIViewController <SubstitutableDetailViewController> *detailViewController = [self.splitViewController.viewControllers objectAtIndex:1];
if ([detailViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *detailNavController = (UINavigationController *)detailViewController;
[[detailNavController.viewControllers objectAtIndex:0] showRootPopoverButtonItem:rootPopoverButtonItem];
}
}
- (void)splitViewController:(UISplitViewController*)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem {
// Nil out references to the popover controller and the popover button, and tell the detail view controller to hide the button.
UIViewController <SubstitutableDetailViewController> *detailViewController = [self.splitViewController.viewControllers objectAtIndex:1];
if ([detailViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *detailNavController = (UINavigationController *)detailViewController;
[[detailNavController.viewControllers objectAtIndex:0] invalidateRootPopoverButtonItem:rootPopoverButtonItem];
}
self.popoverController = nil;
self.rootPopoverButtonItem = nil;
}
- (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation {
UIViewController *detailViewController = [svc.viewControllers objectAtIndex:1];
if ([detailViewController isMemberOfClass:[MySurveysViewController class]]) {
return YES;
}else {
if (UIInterfaceOrientationIsLandscape(orientation)) {
return NO;
}else {
return YES;
}
}
}
I have an iPad App which uses a UISplitViewController as the root controller, I have set up the delegate and I am using a UINavigationController for the DetailView and it seems to work normally.
I want the MasterViewContoller to always be hidden (on all rotations) when a particular viewcontroller is displayed in the DetailView Section. I can do this using the shouldHideViewController method on the UISplitViewController Delegate.
However if I do, then when I change the ViewController in the DetailView Section to another the MasterView is displayed but neither willHideViewController/willShowViewController is called in the delegate.
If I rotate the device and rotate back they are called and it works as expected, but they are not called until the device has been rotated and rotated back to the original orientation.
This causes the popover button to not be displayed on the first rotation after the MasterView has been displayed.
- (void)splitViewController:(UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItem forPopoverController:(UIPopoverController*)pc {
// Keep references to the popover controller and the popover button, and tell the detail view controller to show the button.
barButtonItem.title = @"Survey Sections";
self.popoverController = pc;
self.rootPopoverButtonItem = barButtonItem;
UIViewController <SubstitutableDetailViewController> *detailViewController = [self.splitViewController.viewControllers objectAtIndex:1];
if ([detailViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *detailNavController = (UINavigationController *)detailViewController;
[[detailNavController.viewControllers objectAtIndex:0] showRootPopoverButtonItem:rootPopoverButtonItem];
}
}
- (void)splitViewController:(UISplitViewController*)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem {
// Nil out references to the popover controller and the popover button, and tell the detail view controller to hide the button.
UIViewController <SubstitutableDetailViewController> *detailViewController = [self.splitViewController.viewControllers objectAtIndex:1];
if ([detailViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *detailNavController = (UINavigationController *)detailViewController;
[[detailNavController.viewControllers objectAtIndex:0] invalidateRootPopoverButtonItem:rootPopoverButtonItem];
}
self.popoverController = nil;
self.rootPopoverButtonItem = nil;
}
- (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation {
UIViewController *detailViewController = [svc.viewControllers objectAtIndex:1];
if ([detailViewController isMemberOfClass:[MySurveysViewController class]]) {
return YES;
}else {
if (UIInterfaceOrientationIsLandscape(orientation)) {
return NO;
}else {
return YES;
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我遇到了一个非常类似的问题,使用 Apple 的示例代码和 SubstitutableDetailViewController 委托与旋转相结合。
我所做的是在方向为横向时存储一个
BOOL
,并使用以下代码在willRotateToInterfaceOrientation
上更新它:isLandscape = UIInterfaceOrientationIsLandscape(self.interfaceOrientation);
在
viewWillAppear
上我检查了当前方向是否为横向,如果与存储的值不匹配,则调用此方法:显然我正在使用委托代码由 Apple 提供,但为了完整起见,这些方法如下,并且可以轻松实现:
主视图控制器(左侧)维护对 rootPopoverButtonItem 的引用,这使得这项工作有效。
编辑:请注意,我还在
viewDidLoad
和willRotateToInterfaceOrientation
上调用我的adjustLayoutForOrientation
方法...更好的方法可能是向通知中心注册,但我不确定背景/不可见视图控制器是否会收到这些通知......I was having a very similar problem, using Apple's sample code with the
SubstitutableDetailViewController
delegate combined with rotation.What I did was store a
BOOL
for when the orientation was landscape, updating it onwillRotateToInterfaceOrientation
with this code:isLandscape = UIInterfaceOrientationIsLandscape(self.interfaceOrientation);
On
viewWillAppear
I checked whether the current orientation is landscape, and if it did not match the stored value, called this method:Obviously I am using the delegation code provided by Apple, but for completeness those methods are these and can be implemented easily:
The master view controller (left side) is maintaining the reference to the
rootPopoverButtonItem
, which makes this work.EDIT: Note that I am also calling my
adjustLayoutForOrientation
method onviewDidLoad
andwillRotateToInterfaceOrientation
... A better way might be to register with the Notification Center but I wasn't sure if background/invisible view controllers would get these notifications...