How to animate image in tableview to extend and open another view controller simultaneously? - ios

I'm making a messenger app and I want the user to click on image in my tableview and it should extend to full screen and show different controls on navigation bar.
How do I go about it?
I thought I can take the same image, put UIImageView on top of original cell image and animate it to full screen. But how do I go about presenting different controller without blinks, delays, and animations?
This is done in many messaging applications.

Use a custom transition, to extend the image view from the initial preview size to full screen. When called, return a transition delegate from transitioningDelegate, which in turn should return an animation controller from animationControllerForPresentedController:presentingController:sourceController:. This animation controller will be responsible for the animation that will be performed when presentViewController:animated:completion: is called.
In your animation controller, implement and in it, create the animation:
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
MyChatViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
[[transitionContext containerView] addSubview:toViewController.view];
toViewController.view.frame = [transitionContext.containerView convertRect:fromViewController.imageViewToTransitionFrom.frame fromView:fromViewController.imageViewToTransitionFrom];
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
toViewController.view.frame = [transitionContext finalFrameForViewController:toViewController];
} completion:^(BOOL finished) {
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
Here, MyChatViewController is your chat view controller and imageViewToTransitionFrom holds the image view you wish to transition from.
If you need to push a view controller instead of present it (like WhatsApp does it), there are analogous methods to perform the custom push animation.
You can perform a dismiss/pop animation in a similar manner, or use the default system one.
Read here about custom view controller transitions in iOS7.

Related

How do I see the progress of a pop animation?

I have a master and detail view controller. I have a button that currently disappears after the push segue to the detail and reappears when the pop segue is called, whether it's the interactive gesture or the back button.
This looks really abrupt and I wanted to fade in the alpha on the button with the pop gesture but I don't see any delegate or datasource methods for UINavigationControllerDelegate that show the progress of the pop gesture. Are there any libraries that help with this?
This can be accomplished with a UIView animation.
The idea is to set the alpha of the button to 0 so that it is invisible and then animate it to a value of 1 to create a fade-in effect.
self.myButton.alpha = 0;
[[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.myButton.alpha = 1;
} completion:^(BOOL finished) {
// Code for completion of animation.
}];
This could be placed in the viewDidAppear: method of your view controller.

transitionFromView with UIViewAnimationOptions similar like navigating with UINavigationController

I'm using a similar approach described here for the animation from one view controller to another:
UIWindow *window = (UIWindow *)[[UIApplication sharedApplication].windows firstObject];
[UIView transitionFromView:window.rootViewController.view
toView:vc.view
duration:0.65f
options:UIViewAnimationOptionTransitionCrossDissolve // transition animation
completion:^(BOOL finished){
window.rootViewController = vc;
}];
Looking into the UIViewAnimationOptions I didn't found an option for the default animation, which occurs when doing the same with UINavigationController.
Is it possible to get the same animation behavior (moving the view left)? How?
I tried it with this animation:
[UIView animateWithDuration:0.65 animations:^{
view.transform = CGAffineTransformMakeTranslation(-view.frame.size.width, 0);
} completion:^(BOOL finished) {
// do something
}];
but while translating to the new view the background is completely black instead of bringing the other view controller in.
Now I'm doing it in a different way. I start with my navigation controller and its root view. Then I push another view controller on the stack. In viewDidAppear of this new view controller I'm removing the first view controller from the navigation stack. One downside: You can see the back button for a short time.
The animation solution I tried will need the other view controller animated in. Also I had problems with views which very not layout correctly (because of edgesForExtendedLayout).

Custom UIViewControllerContextTransitioning and black screen [duplicate]

This question already has answers here:
Display clearColor UIViewController over UIViewController
(16 answers)
Closed 7 years ago.
I have a UITableViewController, inside my UITableViewCell i have an imageView when the user taps on it, i present it modally using my own custom UIViewControllerContextTransitioning to make a zoom effect on it, it works like a charm the problem is that when the animation completes and i call the
[transitionContext completeTransition:YES];
My UITableView which is now behind my Modal UIViewController is removed form the view hierarchy so i got a black screen behind it
[containerView addSubview:toViewController.view];
[UIView animateWithDuration:duration delay:0.0 usingSpringWithDamping:damping initialSpringVelocity:1.0 / damping options:0 animations:^{
// blablabla animation stuff
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES];// this line makes my UITableView removed form the view hierarchy
}];
Here is what i've tried so far :
add in the completion bloc the UITableView
[[UIApplication sharedApplication ].keyWindow insertSubview:fromViewController.view belowSubview:containerView];
But this only works on iOS8 ...
Any ideas how to fix this ? thank you !!
Try to set modalPresentationStyle of the presenting view controller to UIModalPresentationCustom

How to bounce child view controller's UICollectionView when the child view controller is presented?

I want to present a child view controller by dropping it from top to the bottom. The child view controller is a UICollectionViewController with several cells in it. I can use the iOS7 UIViewControllerContextTransitioning for the dropping down view controller transition. But if I want only the collection view to bounce (like a ball hit on the ground) when the child view controller is presented, how should I do?
I have try to use UIKit Dynamics and create some UIAnimatorBehavior on the UICollectionView after the transition, like UIGravityBehavior and UIPushBehavior. But they don't seem to work. Maybe I am using them in the wrong way. Is there anyone can give me some hints?
Update
After tried several solutions, I finally came out a solution which is pretty close to what I want. This video shows the result: http://youtu.be/tueXDBMsdt0
But I think there should be a better solution for that. And here is my solution's steps:
Create a UIViewControllerAnimatedTransitioning object, which animate the view controller transition from top to bottom.
The child view controller is a UICollectionViewController. At the end of transition animation, I set child view controller's scrollview content offset to (0, -30), and then complete the transition.
In child view controller's viewDidAppear, animate the content offset back to (0, 0).
Besides, I also follow the instructions in the article: http://www.teehanlax.com/blog/implementing-a-bouncy-uicollectionviewlayout-with-uikit-dynamics/ to set UIKit dynamics animator in cells. When the content offset is changed, then the cells will look like bouncing.
The transition animation code looks like this:
- (void) animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
CGRect frame = [[transitionContext containerView] frame];
CGRect startFrame = frame;
startFrame.origin.y -= CGRectGetHeight(transitionContext.containerView.frame);
[transitionContext.containerView addSubview:fromViewController.view];
[transitionContext.containerView addSubview:toViewController.view];
toViewController.view.frame = startFrame;
[UIView animateWithDuration:0.4 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
toViewController.view.frame = frame;
}
completion:^(BOOL finished) {
((UICollectionViewController*)toViewController).contentOffset = CGPointMake(0, -30);
[transitionContext completeTransition:YES];
}];
}
And in child view controller viewDidAppear:
- (void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.collectionView setContentOffset:CGPointMake(0, 0) animated:YES];
}
But I would still want the cell to bounce more naturally. Any other better solutions?
Important: this can now be done in iOS in one simple line of code:
https://stackoverflow.com/a/23514653/294884
Detailed answer when fuller control is needed:
If you want the same effect between the Screen lock and the Camera on the iPhone, you can use UIViewControllerContextTransitioning
There are a good tutorial here http://www.objc.io/issue-5/view-controller-transitions.html
and here http://www.teehanlax.com/blog/custom-uiviewcontroller-transitions/
if you have a Apple developer account, there are a video about View controller transition : https://developer.apple.com/tech-talks/videos/
The video is named "Architecting Modern Apps, Part 1"
This way work only on iOS7!

Should a UIViewController control a UIView's animations?

I've been pushing myself to learn more MVCS styled programming and am attempting to organize my code better. My main question, is I have a UIViewController that brings up a view when an event occurs. When the view is created and when the view is destroyed, I'd like to run some animations on the view appearing and disappearing. I can do this both in the UIView class I have and in the UIViewController. Once these animations have been established, they do not need to be changed. Should I do this within the UIViewController or the UIView to stay MVC compliant?
The code is currently in my UIView as such:
- (IBAction)removeView
{
NSLog(#"Remove");
if (self.completionBlock != nil) {
[UIView animateWithDuration:1.0f delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
self.transform = CGAffineTransformMakeTranslation(self.frame.origin.x, self.frame.origin.y - self.superview.frame.size.height);
self.alpha = 0; // also fade to transparent
}completion:^(BOOL finished)
{
if (finished) {
[self removeFromSuperview];
}
}];
self.completionBlock(YES);
}
}
Based on your description, you can legitimately do them in either place because the animation does not depend on your application's model. If, however, the animation depended on data from your model, then the controller should perform the animation because the controller sees the model data (but the view does not).
The Views of the ViewController should be the ViewController's minons. You're going to have an easier time having the animation maths happen in the ViewController and have the ViewController update the View and this is the best practice according to MVC.
Also, I think it will be easier for you because you can make the logic based on an action as opposed to based on a class. I find that easier.

Resources