I am creating an animation where the current view controller slides down, revealing the new view controller beneath it. I have got this working with the view, but I would like to include the navigation controller in the view sliding down. So instead of a view sliding down with no navigation bar, It would slide down with the navigation bar at the top. How woould I fix this. Here is how I am doing it with the view:
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
return 5.00;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
[[transitionContext containerView] addSubview:fromViewController.view];
toViewController.view.frame = CGRectMake(0, 0, 320, 568);
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
fromViewController.view.frame = CGRectMake(0, 2000, 320, fromViewController.view.frame.size.height);
toViewController.view.frame = CGRectMake(0, 0, 320, fromViewController.view.frame.size.height);
} completion:^(BOOL finished) {
fromViewController.view.transform = CGAffineTransformIdentity;
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
Related
I am trying to get UIViewControllerContextTransitioning working.
What I want:
What I would like to have, is presenting modal view controller with custom animation and transparent background.
Wthat I did:
I created animator implementing UIViewControllerTransitioningDelegate,
Set for modal controller:
self.modalPresentationStyle = UIModalPresentationCustom;
self.transitioningDelegate = self;
What I achieved so far,
Modal controller animates presenting and dismissing view correctly, but after dismissing is finished, entire app becomes black. I used xCode tool to pick what's in window hierarchy, and there is nothing. My guess is, that I changed VC's superview when adding to context's container.
Animator
#implementation AlertAnimator
const static CGFloat kAnimationDuration = 1.2;
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
UIViewController *to = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController *from = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
if (self.transitionType == ModalAnimatedTransitioningTypePresent) {
[self animatePresentingInContext:transitionContext toVC:to fromVC:from];
} else if (self.transitionType == ModalAnimatedTransitioningTypeDismiss) {
[self animateDismissingInContext:transitionContext toVC:to fromVC:from];
}
}
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{
return kAnimationDuration;
}
- (void)animatePresentingInContext:(id<UIViewControllerContextTransitioning>)transitionContext toVC:(UIViewController *)toVC fromVC:(UIViewController *)fromVC {
CGRect fromVCRect = [transitionContext initialFrameForViewController:fromVC];
CGRect toVCRect = fromVCRect;
toVCRect.origin.y = toVCRect.size.height;
toVC.view.frame = toVCRect;
UIView *container = [transitionContext containerView];
[container addSubview:fromVC.view];
[container addSubview:toVC.view];
[UIView animateWithDuration:kAnimationDuration animations:^{
toVC.view.frame = fromVCRect;
} completion:^(BOOL finished) {
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
- (void)animateDismissingInContext:(id<UIViewControllerContextTransitioning>)transitionContext toVC:(UIViewController *)toVC fromVC:(UIViewController *)fromVC {
CGRect fromVCRect = [transitionContext initialFrameForViewController:fromVC];
fromVCRect.origin.y = fromVCRect.size.height;
UIView *container = [transitionContext containerView];
[container addSubview:toVC.view];
[container addSubview:fromVC.view];
[UIView animateWithDuration:kAnimationDuration animations:^{
fromVC.view.frame = fromVCRect;
} completion:^(BOOL finished) {
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
#end
Code example:
https://www.dropbox.com/s/oaghtgwvga4nxs4/Test.zip?dl=0
Question:
What I am doing wrong and why screen becomes black?
if this is a presenting animator you should not add the fromVC.view as a subview because its already there. This will cause it to bug out. Try it out and tell me what happens. If its a dismissal animator you shouldn't add the presentingViewController to the hierarchy either.
I am implementing a custom transition animation between view controllers, but for some reason my navigation Bar is getting animated along with the transition animation. Is this somehow a auto layout issue? I'm not sure how it would be.
Here is the code I am using to display and dismiss the view controllers with a custom transition.
I would like the navigation bar to not be animated, any ideas as to why this is happening?
-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
// Grab the from and to view controllers from the context
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
if (self.presenting) {
fromViewController.view.userInteractionEnabled = NO;
[transitionContext.containerView addSubview:fromViewController.view];
[transitionContext.containerView addSubview:toViewController.view];
int frameHeight = fromViewController.view.frame.size.height;
CGRect startFrame = fromViewController.view.frame;
startFrame.origin.y = frameHeight;
toViewController.view.frame = startFrame;
//create a view with the same background color to cover up background on bounce effect
UIView *bottomCover = [[UIView alloc]initWithFrame:CGRectMake(0, startFrame.size.height-30, startFrame.size.width, 30)];
[bottomCover setBackgroundColor:[UIColor colorWithRed:0.956 green:0.962 blue:0.956 alpha:1]];
[transitionContext.containerView insertSubview:bottomCover belowSubview:toViewController.view];
__block CGRect endFrame = toViewController.view.frame;
[UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0 usingSpringWithDamping:.75 initialSpringVelocity:1.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
endFrame.origin.y = 0;
toViewController.view.frame = endFrame;
} completion:^(BOOL finished) {
[bottomCover removeFromSuperview];
toViewController.view.frame = endFrame;
[transitionContext completeTransition:YES];
}];
}
else {
toViewController.view.userInteractionEnabled = YES;
[transitionContext.containerView addSubview:toViewController.view];
[transitionContext.containerView addSubview:fromViewController.view];
CGRect endFrame = toViewController.view.frame;
endFrame.origin.y = 0;
fromViewController.view.frame = endFrame;
[UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0 usingSpringWithDamping:.9 initialSpringVelocity:1.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
int frameHeight = toViewController.view.frame.size.height;
CGRect startFrame = fromViewController.view.frame;
startFrame.origin.y = frameHeight;
fromViewController.view.frame = startFrame;
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
//Because there is a bug in Xcode apparently.
[[UIApplication sharedApplication].keyWindow addSubview:toViewController.view];
}];
}
}
I have a animated transition set up for my view controller. I have no problem adding a presented view controller onto my current view, but I cannot dismiss the presented view using dismissViewControllerAnimated:completion:
Also, when the presented view is added, it is a tableView, with selectable cells. When a cell is a selected, a new navigation controller is initiated and is placed on top. When i dismiss the navigation controller, going back to the presented view, the presented view has become full screen, instead of where the animation placed it earlier..
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext {
return 0.5f;
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
// Grab the from and to view controllers from the context
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
// Set our ending frame. We'll modify this later if we have to
CGRect endFrame = CGRectMake(0, 300, 320, 300);
if (self.presenting) {
fromViewController.view.userInteractionEnabled = NO;
[transitionContext.containerView addSubview:fromViewController.view];
[transitionContext.containerView addSubview:toViewController.view];
CGRect startFrame = endFrame;
startFrame.origin.y += 220;
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 += 320;
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
toViewController.view.tintAdjustmentMode = UIViewTintAdjustmentModeAutomatic;
fromViewController.view.frame = endFrame;
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}
Here is the code for my presented view Controller:
shadedView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
shadedView.backgroundColor = [UIColor colorWithRed:224.0/255.0 green:224.0/255.0 blue:224.0/255.0 alpha:0.7];
[self.view addSubview:shadedView];
dismiss = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[dismiss addTarget:self action:#selector(removeViewController) forControlEvents:UIControlEventTouchUpInside];
dismiss.backgroundColor = [UIColor clearColor];
[shadedView addSubview:dismiss];
detailTableViewController = [[DetailTableViewController alloc] initWithFlag:DETAIL andQRCode:o_qrcodeId];
//detailTableViewController.tableView.backgroundColor = [UIColor blackColor];
detailTableViewController.transitioningDelegate = self;
detailTableViewController.modalPresentationStyle = UIModalPresentationCustom;
//detailTableViewController.view.layer.cornerRadius = 12.0f;
[self presentViewController:detailTableViewController animated:YES completion:nil];
I'm trying to build a custom transition in iOS 7. The transition occurs fine, but then when transition context complete transition the modal screen disappears from the view entirely. I've followed several tutorials and I don't see what I am doing wrong. In addition, if I don't call "complete transition" then the view stays, but will not receive any touch events. I checked in Reveal App and there is no view sitting on top of it. Any ideas?
Here is the method where I initiate the transition
- (IBAction)settingsButtonClicked:(id)sender
{
UINavigationController *navigationController =[[self storyboard] instantiateViewControllerWithIdentifier:#"SettingsNavigationViewController"];
navigationController.transitioningDelegate = self;
[self presentViewController:navigationController animated:YES completion:nil];
}
Here is the code for the custom transition:
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *containerView = [transitionContext containerView];
[containerView addSubview:toViewController.view];
CGRect sourceRect = [transitionContext initialFrameForViewController:fromViewController];
CGRect initialTargetFrame = [transitionContext initialFrameForViewController:toViewController];
CGRect initialFrame = CGRectMake(sourceRect.size.width + initialTargetFrame.size.width, 0, initialTargetFrame.size.width, initialTargetFrame.size.height);
CGPoint destinationPoint = CGPointMake(sourceRect.size.width - 500, 0);
CGAffineTransform translate = CGAffineTransformMakeTranslation(initialFrame.origin.x, initialFrame.origin.y);
toViewController.view.transform = translate;
[UIView animateWithDuration:PRESENT_DURATION delay:0 options:UIViewAnimationOptionCurveEaseOut
animations:^{
toViewController.view.transform = CGAffineTransformMakeTranslation(destinationPoint.x, destinationPoint.y);
}
completion:^(BOOL completed) {
if (completed) {
[transitionContext completeTransition:!transitionContext.transitionWasCancelled];
}
}];
}
So I found out what I was doing wrong. I was changing the modalPresentationStyle to custom on the view controller that was being popped onto the navigation controller when I should have been setting it on the navigation controller itself. I added this line to the settingsButtonClicked method above and it worked properly.
navigationController.modalPresentationStyle = UIModalPresentationCustom;
i'm using iOS 7 Custom transition to present a UINavigationController.
but there is a problem. while its animating, the size of navigation bar is only 44points. then after done animating, navigation controllers figured out there is a status bar, so its added 20points for status bar.
my question is, is there possible to set navigation bar to 64point when its animating, so it doesn't change anymore when its done animating.
please see it here for more detail Custom View Transitions
This is my custom animation code:
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
CGRect finalFrame = [transitionContext finalFrameForViewController:toViewController];
UIView *containerView = [transitionContext containerView];
CGRect screenBounds = [[UIScreen mainScreen] bounds];
toViewController.view.frame = CGRectOffset(finalFrame, 0, screenBounds.size.height);
[containerView addSubview:toViewController.view];
NSTimeInterval duration = [self transitionDuration:transitionContext];
[UIView animateWithDuration:duration delay:0.0 usingSpringWithDamping:0.6 initialSpringVelocity:0.0 options:UIViewAnimationOptionCurveLinear animations:^{
toViewController.view.frame = finalFrame;
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}
UPDATE: somebody fixed this problem. but pretty hacky.
add this code after added toViewController.view to containerView.
if ([toViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController* navigationController = (UINavigationController*) toViewController;
UINavigationBar* bar = navigationController.navigationBar;
CGRect frame = bar.frame;
bar.frame = CGRectMake(frame.origin.x, frame.origin.y + 20.0f, frame.size.width, frame.size.height);
}
is there a better way to do it?
I had the same problem, and solved adding the toViewController to container before I set this frame.
Invert the lines like as follow:
[containerView addSubview:toViewController.view];
toViewController.view.frame = CGRectOffset(finalFrame, 0, screenBounds.size.height);