I have a problem where I need to rotate an UIImageView and resize depending if it's Portraite mode or Landscape mode.
I've managed to get the image view to rotate correctly, by doing as the answer in this related problem says: Rotate UIImageView Depending on iPhone Orientation.
This is my code for the rotation (for now I've only focused on rotating it to left landscape):
- (void)rotateImage:(UIImageView *)image duration:(NSTimeInterval)duration
curve:(int)curve degrees:(CGFloat)degrees
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve:curve];
[UIView setAnimationBeginsFromCurrentState:YES];
float angle = DEGREES_TO_RADIANS(degrees);
CGAffineTransform transform = CGAffineTransformRotate(
CGAffineTransformMakeTranslation(
160.0f-self.view.center.x,
240.0f-self.view.center.y
),angle);
image.transform = transform;
[UIView commitAnimations];
}
How I initiate the UIImageView:
UIImage *image = [UIImage imageNamed:#"picture.png"];
self.testImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 400)];
self.testImageView.image = image;
self.testImageView.contentMode = UIViewContentModeScaleAspectFit;
self.testImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
What's happening now is that the Image gets rotated but has the same size as in portrait mode in landscape mode, but is centered (that I understand why, as I did the rotation as the answer to the linked question).
So, what I want is that the image is viewed in fullscreen, as the original image has the scale to fit in fullscreen landscape. As I've set
UIViewContentModeScaleAspectFit
my original naive thought that this would magically rescale to fit the proper landscape scale. That's obviously not the case. Any hints?
Try using UIViewContentModeScaleAspectFit and set in your parent view property autoresizesSubviews to YES. Image should resize automagically.
Related
How can I recreate a slight zoom in to an image using animations?
I have a uiimageview and I want it to look like we zoom in to the image after 1 second, lasting 1 second, but the uiimageview size must not change.
Something like this but the image view changes its size:
[UIView animateKeyframesWithDuration:1
delay:0
options:UIViewKeyframeAnimationOptionBeginFromCurrentState
animations:^{
[UIView addKeyframeWithRelativeStartTime:0
relativeDuration:1
animations:^{
self.imageView.transform =CGAffineTransformMakeScale(1.1, 1.1);
}];
}
completion:^(BOOL finished) {
}];
You can add UIImageView as a child view of UIScrollView and set its zooming options. Here, look at this article.
I'm new in using transformations. And still confusted how they are working.
What I'm trying to do, is to rotate my UIImageView with given angle. But after rotating, it's changing the size of image, getting smaller. I'm also doing scaling for ImageView so it won't be upside down.How to rotate and keep the size, that was given in CGRectMake, when ImageView was allocated ?
UIImageView *myImageView = [[UIImageView alloc]initWithFrame:CGRectMake(x,y,width,height)];
myImageView.contentMode = UIViewContentModeScaleAspectFit;
[myImageView setImage:[UIImage imageNamed:#"image.png"]];
myImageView.layer.anchorPoint = CGPointMake(0.5,0.5);
CGAffineTransform newTransform;
myImageView.transform = CGAffineTransformMakeScale(1,-1);
newTransform = CGAffineTransformRotate(newTransform, 30*M_PI/180);
[self.window addSubview:myImageView];
Thanks a lot!
Ok I promised I'd look into it, so here's my answer:
I create a scene which should be somewhat equivalent to yours, code as follows:
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width/2-100,
self.view.bounds.size.height/2-125,
200,
250)];
imageView.image = [UIImage imageNamed:#"testimage.jpg"];
imageView.contentMode = UIViewContentModeScaleAspectFill;
/*
* I added clipsToBounds, because my test image didn't have a size of 200x250px
*/
imageView.clipsToBounds = YES;
[self.view addSubview:imageView];
NSLog(#"frame: %#",[NSValue valueWithCGRect:imageView.frame]);
NSLog(#"bounds: %#",[NSValue valueWithCGRect:imageView.bounds]);
imageView.layer.anchorPoint = CGPointMake(0.5, 0.5);
imageView.transform = CGAffineTransformMakeRotation(30*M_PI/180);
NSLog(#"frame after rotation: %#",[NSValue valueWithCGRect:imageView.frame]);
NSLog(#"bounds after rotation: %#",[NSValue valueWithCGRect:imageView.bounds]);
This code assumes that you are using ARC. If not add
[imageView release];
at the end.
Using this code the logs look like this:
[16221:207] frame: NSRect: {{60, 105}, {200, 250}}
[16221:207] bounds: NSRect: {{0, 0}, {200, 250}}
[16221:207] frame after rotation: NSRect: {{10.897461, 71.746826}, {298.20508, 316.50635}}
[16221:207] bounds after rotation: NSRect: {{0, 0}, {200, 250}}
As you can see the bounds always stay the same. What actually changes due to the rotation is the frame, because an image which has been rotated by 30°C is of course wider than if it handn't been rotated. And since the center point has been set to the actual center of the view the origin of the frame also changes (being pushed to the left and the top). Notice that the size of the image itself does not change. I didn't use the scale transformation, since the result can be achieved without scaling.
But to make it clearer here are some pictures for you (0°, 30° 90° rotation):
They already look pretty similar, right? I drew the actual frames to make it clear what's the difference between bounds and frame is. The next one really makes it clear. I overlayed all images, rotating them by the negative degrees with which the UIImageView was rotated, giving the following result:
So you see it's pretty straight forward how to rotate images. Now to your problem that you actually want the frame to stay the same. If you want the final frame to have the size of your original frame (in this example with a width of 200 and a height of 250) then you will have to scale the resulting frame. But this will of course result in scaling of the image, which you do not want. I actually think a larger frame will not be a problem for you - you just need to know that you have to take it into account because of the rotation.
In short: it is not possible to have an UIImageView which will have the same frame after rotation. This isn't possible for any UIView. Just think of a rectangle. If you rotate it, it won't be a rectangle after the rotation, will it?
Of course you could put your UIImageView inside another UIView which will have a non-rotated frame with a width of 200 and a height of 250 but that would just be superficial, since it won't really change the fact that a rotated rectangle has a different width and height than the original.
I hope this helps. :)
Do not set the contentMode which UIImageView inherits from UIView and leads to the changes in frame according to scaling,transformation,device rotation in accordance to the UIViewContentMode you select.
Also if you just want to rotate you can just change the frame using :-
[UIView beginAnimations:#"Rotate" context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationDelegate:self];
CGRect frame=yourView.frame;
frame.origin.y+=distance you want to rotate;
yourview.frame=frame;
[UIView commitAnimations];
}
if you dont want the animation just change the frame
Try Using This :-
CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:#"transform.rotation.z"];
animation.fromValue = [NSNumber numberWithFloat:0.0f];
animation.toValue = [NSNumber numberWithFloat: 2*M_PI];
animation.duration = 0.5f;
animation.repeatCount = HUGE_VALF; // HUGE_VALF is defined in math.h so import it
[self.reloadButton.imageView.layer addAnimation:animation forKey:#"rotation"];
I'm building a basic calculator app. The calculator is already fully functional with basic features. The problem I'm having is I ran out of room on the screen to add other, more advanced features. Ideally what I would like to do is create some kind of subclass and view that slides up to to the bottom of the label (where the completed calculations are displayed), when a button on the bottom of the screen is pressed. In other words, I want a view with more operators and computation options to slide up to the bottom of the label and I dont want this view to cover up any digits that are being displayed in the label. Is there anyway to achieve this?
Yes, you can. When your button is pressed, create your new view (with the extra functions), add it as a subview to self.view, and animate a change to it's frame, so that it's frame changes from below the visible view to just below your digits.
Like this:
-(void) buttonPressed {
UIView *myNewView = << create your view >>
myNewView.frame = CGRectMake(0,480, 320,200); // or whatever your width and height are
// 480 means it will be below the visible frame.
[self.view addSubview: myNewView];
float bottom_Y_of_digit_display = 100;// or wherever it is...
[UIView beginAnimations:nil contenxt:nil];
[UIView setAnimationDelay: 0.0];
[UIView setAnimationDuration: 1.0]; // one second.
myNewView.frame = CGRectMake(0,bottom_y_of_digit_display, 320,200);
[UIView commitAnimations];
}
You can use UIAnimations to create an animation out of any changes to UIView properties. You can make your UIView hidden by settings its frame.origin.y to 480 and then change the rect and wrap it in a UIAnimation.
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
CGRect newFrame = newSubView.frame;
newFrame.origin.y -= newSubView.frame.size.height;
newSubView.frame = newFrame;
[UIView commitAnimations];
UPDATE
If you are targeting iOS 4.0 and later then you should use the new UIAnimations interface.
UIViewAnimationOptions options = UIViewAnimationOptionCurveLinear;
[UIView animateWithDuration:0.75 delay:0 options:options
animations:^(){
CGRect newFrame = newSubView.frame;
newFrame.origin.y -= newSubView.frame.size.height;
newSubView.frame = newFrame;
}
completion:^(BOOL finished){
//Do something upon completion
}];
Hey everbody. I have a little issue here. I just want to scale my view, but only to up. I mean, i dont want it move out from original coords, i just want to scale in one direction, without affecting the position.
[UIView beginAnimations: #"myViewAnimation" context: nil];
[UIView setAnimationDuration:1.0];
redView.transform = CGAffineTransformMakeScale(1.0, 3.0);
[UIView commitAnimations];
Thanks!
Origin of all UIView transforms is its layer's anchorPoint, which is in the center of the view by default. Set anchorPoint to CGPointZero so view will be scaled to the right and upwards and its current position will be fixed:
redView.layer.anchorPoint = CGPointZero;
...
UIView beginAnimations: #"myViewAnimation" context: nil];
[UIView setAnimationDuration:1.0];
redView.transform = CGAffineTransformMakeScale(1.0, 3.0);
[UIView commitAnimations];
Note also that view's frame is calculated using its layer's anchorPoint so you may need to also adjust your view's frame accordingly
To access view's layer you will need to add QuartzCore.framework to link with your project and import <QuartzCore/QuartzCore.h> header file.
I am trying to draw a background image in my UIView. This is in a UIAlertView delegate method alertView:
I pop the context because before this I was using a context in a OpenGL view called game.
UIGraphicsPopContext();
UIImage* background = [UIImage imageNamed:#"Background.png"];
[background drawAtPoint:CGPointMake(0.0, 0.0)];
// fade the game out
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
[game setAlpha:0];
[UIView commitAnimations];
[game release];
I get a bunch of error messages such as : CGContextSaveGState: invalid context
I tried it without popping.
I guess what I need to do is find my UIView's CGContextRef, and set that as my current context, but the documentation contains no info regarding CGContextRef.
How can I display my image? I am trying to show the image behind the game view while it fades out.
Thanks.
Solved. All I had to do was put the UIImage in a UIImageView, and add it to the subview of my view.
#hyn is right!
To give an example:
UIImageView *logoView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"38-airplane.png"]];