Rotate UIImageView just like in the Photos.app - ios

I am not sure if this has been directly asked before but I apologize if it has. Pretty much all I trying to accomplish is to rotate a UIImageView that is a subview within a UIScrollView the same exact way it is in the Photos.app.
There are many links around S.O that show code to rotate the image itself but I am not sure if that is the way it is done in the Photos.app.
If anyone can clear up the way it is done in the Photos.app that would be great!
Thanks!

I don't understand what you mean with the photo app, but there are not too many ways to rotate a view. Basically there are 2 ways: the first way would be to apply a CGTransformation like in the following example:
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
[imgView setImage:[UIImage imageNamed:#"polaroid_spacer"]];
[self addSubview: imgView];
[UIView animateWithDuration:0.3f delay:5.f options:UIViewAnimationOptionCurveEaseIn animations:^{
[imgView setTransform:CGAffineTransformMakeRotation(M_PI_2)];
} completion:NULL];
The other way would be to apply a CATransform to the view's layer:
//be sure to include quartz
#import <QuartzCore/QuartzCore.h>
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
[imgView setImage:[UIImage imageNamed:#"polaroid_spacer"]];
[self addSubview: imgView];
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:#"transform"];
[anim setToValue: [NSValue valueWithCATransform3D: CATransform3DMakeRotation(M_PI_2, 0, 0, 1)]];
[anim setDuration: 3.f];
[anim setBeginTime: (CACurrentMediaTime() + 5.f)];
[imgView.layer addAnimation:anim forKey:#"myAwesomeAnim"];
Both can be used to accomplish this. But if you don't know too much about Core Animation you should use Core Graphics. It's easier to get some results with that because you can for example use the UIView animations.

Related

How to set Shadow for a UISegmentedControl?

I have this method applyShadow which applies the shadow , and this works fine for UIViews and for UINavigationBar,but When I try it to UISegmentedControl, it doesnt work.
-(void) applyShadow
{
[self.layer setShadowOffset:CGSizeMake(0, 1.0)];
[self.layer setShadowRadius:1.0];
[self.layer setShadowOpacity:.15];
self.layer.shouldRasterize = YES;
self.layer.rasterizationScale = [UIScreen mainScreen].scale;
}
I tried this but didn't work:
[self.tabSegment applyShadow];
It is not the best answer but try adding UISegmentedControl to a UIView as a subview. But be careful about setting the frames of each other the same.
Adding a UIView behind the Segment bar didnt work out for me, so I did find a quick solution to it, I added a UIView below the segment bar and applies shadow to it.If anyone come up with a better solution,I always welcome them.
self.shadowView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 1)];
self.shadowView.backgroundColor = [UIColor whiteColor];
[self.shadowView applyShadow];
[self.view addSubview:self.shadowView];

Unable to add subviews to a UIView when using the View's layer as a mask

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.

UIView Animation does not actually set new values?

I'm having a problem with UI animations.
I have a uiview: theView.
I animate theView to move to some random position on the mainView. It moves from point A to point B and changes its scale from 1.0 to 1.5;
So after the animation, the view is bigger and in a new position.
I call a second animation, by button. This one only move theView.
After the animation, the view has moved. However, the view is no longer bigger, its scale is back at 1.0.
So do these animation values not become theViews new values for size,position,ex?
I will post code soon, because it of course may be a careless error I am missing.
If its UIView animation.
- (void)viewDidLoad
{
[super viewDidLoad];
_yourView = [[UIView alloc]initWithFrame:CGRectMake(300, 300, 100, 100)];
[_yourView setBackgroundColor:[UIColor redColor]];
[self.view addSubview:_yourView];
[UIView animateWithDuration:1.0f animations:^{
[_yourView setFrame:CGRectMake(400, 400, 150, 150)];
} completion:nil];
UIButton *aMoveButton = [[UIButton alloc] initWithFrame:CGRectMake(10.0f, 5.0f, 60.0f, 40.0f)];
[aMoveButton setTitle:#"MoveView" forState:UIControlStateNormal];
[aMoveButton addTarget:self action:#selector(moveYourView) forControlEvents:UIControlEventTouchDown];
[self.view addSubview:aMoveButton];
}
-(void)moveYourView{
[UIView animateWithDuration:1.0f animations:^{
[_yourView setFrame:CGRectMake(300, 500, 150, 150)];
} completion:nil];
}
Believe me this works and it actually changes the view's values for size,position.
I cannot post a comment, so I would just like to suggest that you say UIView, i'm not 100% sure, so dont take my word for it, but im pretty sure you should use UIImageView instead. Hope that helps a little :)
// create the view that will execute our animation
UIImageView* campFireView = [[UIImageView alloc] initWithFrame:self.view.frame];
// load all the frames of our animation
campFireView.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"campFire01.gif"],
[UIImage imageNamed:#"campFire02.gif"],
[UIImage imageNamed:#"campFire03.gif"],
[UIImage imageNamed:#"campFire04.gif"],
[UIImage imageNamed:#"campFire05.gif"],
[UIImage imageNamed:#"campFire06.gif"],
[UIImage imageNamed:#"campFire07.gif"],
[UIImage imageNamed:#"campFire08.gif"],
[UIImage imageNamed:#"campFire09.gif"],
[UIImage imageNamed:#"campFire10.gif"],
[UIImage imageNamed:#"campFire11.gif"],
[UIImage imageNamed:#"campFire12.gif"],
[UIImage imageNamed:#"campFire13.gif"],
[UIImage imageNamed:#"campFire14.gif"],
[UIImage imageNamed:#"campFire15.gif"],
[UIImage imageNamed:#"campFire16.gif"],
[UIImage imageNamed:#"campFire17.gif"], nil];
// all frames will execute in 1.75 seconds
campFireView.animationDuration = 1.75;
// repeat the annimation forever
campFireView.animationRepeatCount = 0;
// start animating
[campFireView startAnimating];
// add the animation view to the main window
[self.view addSubview:campFireView];

Shrink UIView from left to right

I have the following code to shrink a UIView from left to right and remove it from super view after the animation finished:
UIView* coverView = [[UIView alloc]initWithFrame:CGRectMake(100, 100, 300, 50)];
UIImageView* imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"swipe_rl.png"]];
[imageView setContentMode:UIViewContentModeScaleToFill];
[imageView setFrame:coverView.bounds];
[coverView addSubview:imageView];
[coverView setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
coverView.clipsToBounds = YES;
[self.view addSubview:coverView];
CGRect frame = coverView.frame ;
[UIView animateWithDuration:5.0 animations:^{
[coverView setFrame:CGRectMake(frame.origin.x + frame.size.width, frame.origin.y, 0, frame.size.height)];
} completion:^(BOOL finished){
[coverView removeFromSuperview];
}];
However, the left part of the picture stays and the right part of the picture disappears as you can see in the pictures. For a specific purpose, I want the left part disappears and the right part stays. How can I do it?
For those who want to know why I want this:
- Basically, I want a display-from-left-to-right animation (It means you have a picture and the left of the picture appears first and the the middle and the whole picture appears)
- I do this by adding a second view above the first picture and then shrink the second view from left to right. The first view will then be revealed from left to right.
- Look at http://i1289.photobucket.com/albums/b510/yenmach/right_to_left_zps80b9e9bb.jpg and http://i1289.photobucket.com/albums/b510/yenmach/left_to_right_zps9214dc4a.jpg
//try this.......
CGRect frame = coverView.frame ;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:5.0];
[UIView setAnimationDelay:0];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
imageView.frame = CGRectMake(frame.origin.x - 2*frame.size.width,imageView.frame.origin.y, frame.size.width, frame.size.height);
coverView.frame = CGRectMake(frame.origin.x + frame.size.width, frame.origin.y, frame.size.width, frame.size.height);
[UIView commitAnimations];
Not exactly a solution but a workaround, If you are going to be using this with a consistent background (ideally a solid colour) you could just have another view animate overtop of the image view and then remove both once the animation is done.
Try changing UIImageView contentMode property,
[imageView setContentMode: UIViewContentModeRight];
I was having same kind of requirement and this worked fine for me at that time.

UIView transitionFromView not animating in container

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.

Resources