I use the following code to present a viewcontroller. My problem is: After the animation completes, the transparent main background becomes opaque black.
How can I f
You can present a view controller, and still have the original view controller visible underneath, like a form, in iOS 7. To do so, you will need to do two things:
Set the modal presentation style to custom:
viewControllerToPresent.modalPresentationStyle = UIModalPresentationCustom;
Set the transitioning delegate:
viewControllerToPresent.transitioningDelegate = self;
In this case, we have set the delegate to self, but it can be another object. The delegate needs to implement the two required methods of the protocol, possible like so:
- (id )animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
SemiModalAnimatedTransition *semiModalAnimatedTransition = [[SemiModalAnimatedTransition alloc] init];
semiModalAnimatedTransition.presenting = YES;
return semiModalAnimatedTransition;
}
- (id )animationControllerForDismissedController:(UIViewController *)dismissed
{
SemiModalAnimatedTransition *semiModalAnimatedTransition = [[SemiModalAnimatedTransition alloc] init];
return semiModalAnimatedTransition;
}
At this point you may be thinking, where did that SemiModalAnimatedTransition class come from. Well, it is a custom implementation adopted from teehan+lax's blog.
Here is the class's header:
@interface SemiModalAnimatedTransition : NSObject
@property (nonatomic, assign) BOOL presenting;
@end
And the implementation:
#import "SemiModalAnimatedTransition.h"
@implementation SemiModalAnimatedTransition
- (NSTimeInterval)transitionDuration:(id )transitionContext
{
return self.presenting ? 0.6 : 0.3;
}
- (void)animateTransition:(id )transitionContext
{
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
CGRect endFrame = fromViewController.view.bounds;
if (self.presenting) {
fromViewController.view.userInteractionEnabled = NO;
[transitionContext.containerView addSubview:fromViewController.view];
[transitionContext.containerView addSubview:toViewController.view];
CGRect startFrame = endFrame;
startFrame.origin.y = endFrame.size.height;
toViewController.view.frame = startFrame;
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
fromViewController.view.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed;
toViewController.view.frame = endFrame;
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}
else {
toViewController.view.userInteractionEnabled = YES;
[transitionContext.containerView addSubview:toViewController.view];
[transitionContext.containerView addSubview:fromViewController.view];
endFrame.origin.y = endFrame.size.height;
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
toViewController.view.tintAdjustmentMode = UIViewTintAdjustmentModeAutomatic;
fromViewController.view.frame = endFrame;
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}
}
@end
Not the most straightforward solution, but avoids hacks and works well. The custom transition is required because by default iOS will remove the first view controller at the end of the transition.
UPDATE:
For iOS 8, once again the landscape has changed. All you need to do is use the new presentation style .OverCurrentContext, ie:
viewControllerToPresent.modalPresentationStyle = UIModalPresentationOverCurrentContext;