When i switch View In TabBarController the ScrollView Stop Scroll,How to Solve it? - ios

in Controller A: here the Code:
[UIView animateWithDuration:5 animations:^{
[self.awardScrollView setContentOffset:CGPointMake(self.awardScrollView.frame.size.width * 19, 0)];
} completion:^(BOOL finished) {
isFinished = YES;
}];
i set 5s to finish the animation,but i switch controller to B with TabBarController,i found the animation is stop in Controller A.How can i let the ScrollView continue Scroll Background in Controller A even i Switch to Controller B?

Core Animation won't animate a view that's not in the on-screen view hierarchy. When a view is removed from the on-screen view hierarchy, Core Animation removes all animations from the view.
You can add another animation when the view comes back on screen if you want.

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).

Keyframe animation takes long time to start after UIView animateWithDuration is called

I am using the following method to chain animations:
[UIView animateWithDuration:0.3 delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^(){
// Animations here
}
completion:^(BOOL finished) {
if (finished) {
// Chained animation
}
}];
These animations play whenever I present and dismiss a view controller, call it View Controller 1.
When I load a second view controller, View Controller 2, I display an interstitial loading view on top of mainWindow, where mainWindow is
UIWindow *mainWindow = [[[UIApplication sharedApplication] delegate] window];
This interstitial loading view shows a spinner that is animated using a keyframe animation.
The problem I am running into is that if I load View Controller 1 multiple times (say 5+ times), then load View Controller 2, the spinner animation begins to take a long time to start. After entering View Controller 1 several more times, then entering View Controller 2, View Controller 2's animation takes so long to begin that the loading view is removed before the spinner ever gets a chance to start animating.
Does anyone know what might be causing this behavior? Does it have anything to do with UIView animations not being properly removed when I leave View Controller 1?
Call the method in the main_queue , this solved my problem.
dispatch_async(dispatch_get_main_queue(), ^{
[UIView animateWithDuration:0.3 delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^(){
// Animations here
}
completion:^(BOOL finished) {
if (finished) {
// Chained animation
}
}];
});

UIViewControllerAnimatedTransitioning with UIStatusBarAnimation

i implemented the method in ViewController A
- (BOOL)prefersStatusBarHidden {
return NO;
}
i implemented the method in ViewController B
- (BOOL)prefersStatusBarHidden {
return YES;
}
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
return UIStatusBarAnimationSlide; // when doing hiding animation i want it to slide up
}
i implemented a class T that conforms for viewController transitioning say AtoBTransition, i used this ViewControllerTransition for Transitioning From vc(viewcontroller) A to vc B. when transitioning to vc B i want the status bar to slide up (hide with sliding animation) but in this case, it seems that it doesn't do that the sliding animation.
Questions: Just Assume that i didn't do UIStatusBar related code in class T, and didn't add the value View controller-based status bar appearance in info plist. And transition T works perfectly as needed.
i'm sure the code reads in -preferredStatusBarUpdateAnimation by doing breakpoint or logging but why it didn't hiding statusbar animation by sliding? when i toggle to slowmotion in simulator. it appears it doesn't do animation.
my theory is that it conflicts with transition animation context, so is it possible to do animation of hiding UIStatusBar within the implementation of T as part of its transition scheme?
is it possible to do UIStatusBar animation along with ViewControllerAnimationTransition?
feel free to clear some stuff. thanks ahead.. :)
I don't think you can do this directly with iOS 7 's view controller transition API.
Now, I'm assuming based on the hooks to this API and the status bar API that the status bar is an animal unto itself and is not available for animating with a custom transition. I think this is the case because when the UIViewControllerContextTransitioning transitionContext is created for you view controller A is already added to it's containerView and because you're responsible for adding view controller B to the containerView (because you need to transition to it) all of view controller B's status bar manipulation methods are fired when you do so.
However, you can animate UIApplication's keyWindow's frame during your animation transition So in the -animateTransition: method of your class that implements UIViewControllerAnimatedTransitioning.
[UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
[UIApplication sharedApplication].keyWindow.frame = CGRectMake(0, 0, 320, 568); // move frame up
} completion:^(BOOL finished) {
// assuming
[UIApplication sharedApplication].keyWindow.frame = CGRectMake(0, 20, 320, 568); //move frame down
}];
If you go with this approach, you'll probably need to adjust the frame of the key window in view controller A to drop below the status bar and be styled light/dark as needed. Then do the opposite to get the effect you want in view controller B. Its nasty, but it could work.

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!

Resources