I want to include some UIKeyCommands
in my app. My app consists of one UISplitViewController
that forces the master to be always visible on iPad full screen. On smaller screen it works like it normally would.
Now, I've implemented some UIKeyCommands
in the MasterViewController
and some in the DetailViewController
. However, the app will only show those in DetailViewController
. So I put all of them in the RootSplitViewController
, but that will show all of them, even when the MasterViewController
is hidden in iOS 9's splitview.
What I want though, is for it to show all when the app is fullscreen on iPad and thus the MasterViewController
is forced on screen together with the DetailViewController
. And when the view is small (ie 50-50) and the MasterViewController
is hidden, I want it to only show those of the window that's on screen.
Any ideas on how to achieve this?
In the end I managed to do this - although in a not-so-pretty way.
The UIKeyCommands
are added to the RootSplitViewController
.
- (NSArray *)keyCommands {
if (self.view.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassRegular) {
return @[
[UIKeyCommand keyCommandWithInput:@"r" modifierFlags:UIKeyModifierCommand action:@selector(changeRestaurant:) discoverabilityTitle:@"Change restaurant"],
[UIKeyCommand keyCommandWithInput:@"t" modifierFlags:UIKeyModifierCommand action:@selector(changeTable:) discoverabilityTitle:@"Change table"]
];
} else {
if (self.masterIsVisible == YES) {
return @[
[UIKeyCommand keyCommandWithInput:@"t" modifierFlags:UIKeyModifierCommand action:@selector(changeRestaurant:) discoverabilityTitle:@"Change restaurant"]
];
} else {
return @[
[UIKeyCommand keyCommandWithInput:@"t" modifierFlags:UIKeyModifierCommand action:@selector(changeTable:) discoverabilityTitle:@"Change table"]
];
}
}
}
Those methods call the actual methods in the specific UIViewController
.
- (void)changeRestaurant:(id)sender {
UINavigationController *nav = (UINavigationController *)[self.viewControllers objectAtIndex:0];
RestaurantController *master = [nav.viewControllers objectAtIndex:0];
[master changeRestaurant];
}
- (void)changeTable:(id)sender {
UINavigationController *nav = (UINavigationController *)[self.viewControllers objectAtIndex:1];
TableController *detail = [nav.viewControllers objectAtIndex:0];
[detail changeTable:sender];
}
In order for this to work I added a BOOL
to the UISplitViewController
.
@interface RootSplitViewController : UISplitViewController
@property (nonatomic) BOOL masterIsVisible;
@end
Which is then called in the MasterViewController
.
- (void)viewDidDisappear:(BOOL)animated {
RootSplitViewController *rootView = (RootSplitViewController *)self.splitViewController;
rootView.masterIsVisible = NO;
}
- (void)viewDidAppear:(BOOL)animated {
RootSplitViewController *rootView = (RootSplitViewController *)self.splitViewController;
rootView.masterIsVisible = YES;
}
I know this might not be the pretties method, but it works. If anyone knows a better way to do it, I'd love to hear your feedback.