code:
[UIView transitionFromView:vwOne toView:vwTwo
duration:1.0
options:UIViewAnimationOptionTransitionFlipFromLeft
completion:NULL]
I created two views and made IBOutlet connection. I tried a simple flip animation.what i tried is flip animate UIView only.but entire VIEW CONTROLLER is animating.
I taken the code for you from here, if you need more reference please refer that link
UIView *fromView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, containerView.frame.size.width, containerView.frame.size.height)];
fromView.backgroundColor = [UIColor blueColor];
UIView *toView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, containerView.frame.size.width, containerView.frame.size.height)];
toView.backgroundColor = [UIColor purpleColor];
[containerView addSubview:fromView];
[CATransaction flush];
[UIView transitionFromView:fromView toView:toView duration:0.4f options:UIViewAnimationOptionTransitionFlipFromLeft completion:NULL];
Related
I want to create a tipsView with a pop animate like this:
tips
But as the gif show, there is a very thin gap between the two connected view while animating;
Then I made a demo to find out the main cause and finally got the cornerRadius property. Here is demo code:
- (void)viewDidLoad {
[super viewDidLoad];
self.containerView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 214, 40)];
[self.view addSubview:self.containerView];
self.subView1 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 214, 34)];
self.subView1.backgroundColor = [UIColor grayColor];
self.subView1.layer.cornerRadius = 6.0;
self.subView1.layer.masksToBounds = YES;
[self.containerView addSubview:self.subView1];
self.subView2 = [[UIView alloc] initWithFrame:CGRectMake(100, 34, 14, 6)];
self.subView2.backgroundColor = [UIColor darkGrayColor];
[self.containerView addSubview:self.subView2];
self.containerView.transform = CGAffineTransformMakeScale(0.01, 0.01);
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(tap:)];
[self.view addGestureRecognizer:tap];
}
- (void)tap:(UITapGestureRecognizer *)sender {
[UIView animateWithDuration:10 animations:^{
self.containerView.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished) {
[UIView animateWithDuration:10 animations:^{
self.containerView.transform = CGAffineTransformMakeScale(0.01, 0.01);
}];
}];
}
The gif:
demo
and once I delete the line which used to set the cornerRadius property(or just set to 0), its behavior was in line with expectations. The gif after deleting:
demo after deleting
I wander why the cornerRadius property cause this result, and how I can fix it.
I find a similar question and the solution here, but I don't want to combine two views into one with bezier curve.
I'm trying to flip between a front view and a back view, like a page of a book. I ran the following test code in a view controller and no animation happened. I only saw the back view (red square) appear statically for 2 seconds. What's wrong?
UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 100.0)];
containerView.backgroundColor = [UIColor greenColor];
[self.view addSubview:containerView];
UIView *backView = [[UIView alloc] initWithFrame:containerView.bounds];
backView.backgroundColor = [UIColor redColor];
[containerView addSubview:backView];
UIView *frontView = [[UIView alloc] initWithFrame:containerView.bounds];
frontView.backgroundColor = [UIColor blueColor];
[containerView addSubview:frontView];
[UIView transitionFromView:frontView
toView:backView
duration:2.0
options:UIViewAnimationOptionTransitionFlipFromRight
| UIViewAnimationOptionShowHideTransitionViews
completion:^(BOOL finished) {
[containerView removeFromSuperview];
}];
If you declare your frontView, backView and containerViewas ivars:
#interface yourViewController ()
{
UIView *backView;
UIView *frontView;
UIView *containerView;
}
Then place your view initialization code within viewDidLoad:
UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 100.0)];
containerView.backgroundColor = [UIColor greenColor];
[self.view addSubview:containerView];
UIView *backView = [[UIView alloc] initWithFrame:containerView.bounds];
backView.backgroundColor = [UIColor redColor];
[containerView addSubview:backView];
UIView *frontView = [[UIView alloc] initWithFrame:containerView.bounds];
frontView.backgroundColor = [UIColor blueColor];
[containerView addSubview:frontView];
And finally place your animation code within a method:
- (void)flippingViewTransitionAnimation
{
[UIView transitionFromView:frontView
toView:backView
duration:2.0
options:UIViewAnimationOptionTransitionFlipFromRight | UIViewAnimationOptionShowHideTransitionViews
completion:^(BOOL finished) {
[containerView removeFromSuperview];
}];
}
And subsequently call the above method from within viewDidAppear, you should then be able to see the animation run.
I am trying to animate a UIView with a popover kind of effect, and I want the background of the UIView to have that ios7 style blur as the background.
Making this slightly more complicated, I'd also like to be able to apply a transform to the popover and its contents by dragging the corner, much like a chat in the Facebook app.
Now, my approach is basically this: take a blurred snapshot of the window, add a UIImageView as a subview of the controller's view, mask that imageView with the UIView popover. However, I am then finding that I can not interact with that UIView at all - subviews don't show up, gesture recognizers don't fire, etc.
Here is my code:
UIWindow *mainWindow = [[UIApplication sharedApplication] keyWindow];
CGRect frame = [self.tableView.tableHeaderView convertRect:self.displayView.frame toView:self.view];
UIView *view = [UIView new];
view.frame = frame;
view.backgroundColor = [UIColor blackColor];
view.layer.cornerRadius = 10.f;
view.tag = 100;
//Take the snapshot
UIGraphicsBeginImageContextWithOptions(mainWindow.rootViewController.view.bounds.size, YES, [[UIScreen mainScreen] scale]);
[mainWindow drawViewHierarchyInRect:mainWindow.bounds afterScreenUpdates:NO];
UIImage *screenImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImage *blur = [screenImage applyDarkEffect];
UIImageView *imageView = [[UIImageView alloc] initWithImage:blur];
imageView.frame = self.view.bounds;
[self.view addSubview:imageView];
[self.view addSubview:view];
imageView.layer.mask = view.layer;
//Animate the view
[UIView animateKeyframesWithDuration:1.4f delay:0.0f options:UIViewKeyframeAnimationOptionCalculationModeCubic
animations:^{
[UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.75 animations:^{
view.frame = CGRectInset(mainWindow.frame, 30, 40);
}];
[UIView addKeyframeWithRelativeStartTime:0.75 relativeDuration:0.05 animations:^{
view.frame = CGRectInset(mainWindow.frame, 20, 30);
}];
[UIView addKeyframeWithRelativeStartTime:0.8 relativeDuration:0.20 animations:^{
view.frame = CGRectInset(mainWindow.frame, 25, 35);
}];
} completion:^(BOOL finished) {
//This does nothing.
UIView *test = [UIView new];
test.frame = CGRectMake(100, 100, 100, 100);
test.backgroundColor = [UIColor redColor];
[view addSubview:test];
}];
Any insights in to why this isn't working? Or alternative approaches?
One alternate approach I thought of would be to roll my own keyframe animation: Add the imageView as a subview of the 'view', use an update timer, and calculate the frame of the view for each frame, offsetting the image view appropriately. But I was hoping there would be an easier way around this issue.
If you create a brand new single view app and put this code behind a button:
UIView *blah = [[UIView alloc] initWithFrame:CGRectMake(0,0,100,100)];
blah.backgroundColor = [UIColor grayColor];
[UIView transitionWithView:blah duration:1
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
[self.view addSubview:blah];
}
completion:^(BOOL finished){
}];
The subview is added immediately with no animation. If you add the subview first then try to animate it... you get the same problem.
UIView *blah = [[UIView alloc] initWithFrame:CGRectMake(0,0,100,100)];
[self.view addSubview:blah];
[UIView transitionWithView:blah duration:1
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
blah.backgroundColor = [UIColor grayColor];
}
completion:^(BOOL finished){
}];
How on Earth do you animate a flip for a subview while or immediately after adding it?
You generally need to have the container that constrains the animation to be in place already:
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect frame = CGRectMake(0, 0, 100, 100);
_container = [[UIView alloc] initWithFrame:frame];
_container.backgroundColor = [UIColor lightGrayColor];
[self.view addSubview:_container];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
UIView *subview = [[UIView alloc] initWithFrame:_container.bounds];
subview.backgroundColor = [UIColor darkGrayColor];
[UIView transitionWithView:_container
duration:1.0
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
[_container addSubview:subview];
}
completion:NULL];
}
This is worth a try:
UIView *blah = [[UIView alloc] initWithFrame:CGRectMake(0,0,100,100)];
blah.backgroundColor = [UIColor grayColor];
[self.view addSubview:blah];
blah.alpha = 0.0; //Or with blah.hidden = TRUE and then FALSE inside the animation block
[UIView transitionWithView:blah
duration:1
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
blah.alpha = 1.0;
}
completion:^(BOOL finished){
}];
I'm using UIView transitionFromView to flip between two views. I'm currently doing the following in a UIView subclass:
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"img.png"]];
imgView.frame = CGRectMake(0, 0, 100, 100);
UIView *detailView = [[UIView alloc] initWithFrame:imgView.frame];
detailView.backgroundColor = [UIColor redColor];
detailView.frame = imgView.frame;
[self addSubview:imgView];
[UIView transitionFromView:imgView toView:detailView duration:1.0
options:UIViewAnimationOptionTransitionFlipFromLeft
completion:^(BOOL finished){
}
];
This works as expected. The transition performs as it should. The issue is that I need the transition to take place in a subview of the view that the previous code is contained within. So, I put everything in a container and try to animate that:
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"img.png"]];
imgView.frame = CGRectMake(0, 0, 100, 100);
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
UIView *detailView = [[UIView alloc] initWithFrame:imgView.frame];
detailView.backgroundColor = [UIColor redColor];
detailView.frame = imgView.frame;
[container addSubview:imgView];
[self addSubview:container];
[UIView transitionFromView:imgView toView:detailView duration:1.0
options:UIViewAnimationOptionTransitionFlipFromLeft
completion:^(BOOL finished){
}
];
But in this case, the animation doesn't run. Instead, I only see the final result without the transition. Can anyone help me figure out how the two cases differ?
The same problem is described here, but I don't feel the existing 'solution' is sufficient to fully describe this behavior.
Transition behavior using transitionFromView and transitionWithView
Consider delaying the animation to another run loop, using dispatch_after and performSelector:withObject:afterDelay:
or use [CATransaction flush] after you add the subviews
More info at http://andrewmarinov.com/working-with-uiviews-transition-animations/
I don't know why the first one works, but this is not the correct way to use this method. The view being transitioned away from will be removed from the hierarchy and the view being transitioned to will be added as part of the animation. So skip adding detailView (or use the UIViewAnimationOptionShowHideTransitionViews option.