Reputation: 55594
Is there a shorter way to present a view controller, when wanting to support iOS 4 and above (for the iPhone 3G) in a universal app?
Currently I have this below, but I dislike how I need a UIPopoverController property, which I need especially because if the view controller is say for picking an image, when an image is picked the popover needs to be dismissed.
@interface SASuccessViewController ()
@property (nonatomic, retain) UIPopoverController *myPopoverController;
@end
@implementation SASuccessViewController
-(void)showViewController:(UIBarButtonItem *)sender {
UIViewController *viewController = [[UIViewController alloc] init];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
if ([self respondsToSelector:@selector(presentViewController:animated:completion:)]) {
[self presentViewController:viewController animated:NO completion:nil];//iOS 5 and above
} else {
[self presentModalViewController:viewController animated:NO]; //iOS 4, deprecated in iOS 6
}
} else {
if (!self.myPopoverController) {
self.myPopoverController = [[[UIPopoverController alloc] initWithContentViewController:viewController] autorelease];
} else {
[self.myPopoverController setContentViewController:viewController];
}
[self.myPopoverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
[viewController release];
}
-(void)dealloc {
[_popoverController release];
[super dealloc];
}
@end
Considering that when iOS 4 was the latest (and not a Universal app), the method would be just:
-(void)showViewController:(UIBarButtonItem *)sender {
UIViewController *viewController = [[UIViewController alloc] init];
[self presentModalViewController:viewController animated:NO];
[viewController release];
}
What I have now seem quite bloated. Is there a better way of showing a view controller on Universal apps (let alone supporting iOS 4)?
Upvotes: 2
Views: 2045
Reputation: 1501
You can create a instance of your UIViewController
and set the modal presentation style to UIModalPresentationStyle
to formsheet or to currentContext if you want it in a popover and give animation using transitionStyle
and then finally present it.
I hope this will solve your problem.
UIViewController *viewController = [[UIViewController alloc] init];
[viewController setModalPresentationStyle:UIModalPresentationFormSheet];
[viewController setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[self presentViewController:viewController animated:YES completion:nil];
so in case it doesnot work with ios4 we can use directly presentasmodalview controller
Upvotes: 0
Reputation: 16714
Unfortunately there is not a much better way to present modal view in a universal app. The logic you have is all pretty much necessary. Here are some tips, though:
Considering that you are not specifying a completion block, it is probably okay to stick with the deprecated presentViewController:animated:
method until you remove support for iOS 4.0. In other words, you could just do this:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
[self presentModalViewController:viewController animated:NO];
}
Or, as someone else stated, you could create a UIViewController category for the presentModalViewController methods. At least this will clean up your UIViewController a bit.
If your SASuccessViewController inherits directly from UIViewController, you might consider creating another UIViewController for SASuccessViewController to inherit from. For example, MasterViewController could be a view controller that any of your view controller's could inherit from. The idea here is to clean up your view controllers by moving the code to your super class, and at the same time eliminate repetition of code when presenting modal controllers in different view controllers.
@interface MasterViewController ()
@property (nonatomic, retain) UIPopoverController *popoverController;
- (void)presentViewController:(UIViewController *)viewController origin:(id)origin;
@end
@implementation MasterViewController
@synthesize popoverController;
- (void)presentViewController:(UIViewController *)viewController origin:(id)origin {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
if ([self respondsToSelector:@selector(presentViewController:animated:completion:)]) {
[self presentViewController:viewController animated:NO completion:nil];//iOS 5 and above
} else {
[self presentModalViewController:viewController animated:NO]; //iOS 4, deprecated in iOS 6
}
} else {
if (!self.popoverController) {
self.popoverController = [[[UIPopoverController alloc] initWithContentViewController:viewController] autorelease];
} else {
[self.popoverController setContentViewController:viewController];
}
if(![self.popoverController isPopoverVisible]) {
if([origin isKindOfClass:[UIBarButtonItem class]]) {
[self.popoverController presentPopoverFromBarButtonItem:origin
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
} else {
[self.popoverController presentPopoverFromRect:CGRectZero inView:origin permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
}
}
}
@end
And then you could just do this from your SASuccessViewController
:
-(void)showViewController:(UIBarButtonItem *)sender {
[self presentViewController:x origin:sender];
}
Upvotes: 1
Reputation: 4843
You could write a category on UIViewController to do this:
@implementation UIViewController (PresentViewController)
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion;
@end
@interface UIViewController (PresentViewController)
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
if([super respondsToSelector:@selector(presentViewController:animated:completion:)]){
[super presentViewController:viewControllerToPresent animated:flag completion:completion];
} else {
[super presentModalViewController:viewControllerToPresent animated:flag];
}
}
Upvotes: 1