Get height based on fixed width UIImageView image - objective-c

How can I get height for UIImageView based on fixed (310.0f) UIImageView width for real looking image ?
So the thing should work for placing UIImageViews in UITableViewCells (thats not important for question). But I want to point on some examples: 9gag app, facebook, google+ and other feeds with images that resize and are put in UITableViewCell

Divide the width you want by the actual width of the image. Then multiple that number with the actual height.
UIImage* image = [UIImage imageNamed:#"someImage.png"];
CGSize imageSize = image.size;
CGFloat newHeight = (310.0 / imageSize.width) * imageSize.height;

Related

Make image smaller inside UIImageView

I have an UIImageView that shows and image of a creditCard, My problem is that I want to make boarders around it, so the credit card wont touch the edges of the UIimageView, I dont want to change the UIImageView position on the screen so what can I do ?
image 1
image 2
( unlike the example of the blue card it dosnt have to leave spaces only from the sides, it could shrink it from all sides )
You basically have (3) three options that can fix this.
Adjust the UIViewContentMode contentMode of the UIImageView so that it appropriately displays the image (this will only work however if the image you are using scales to fit without touching the border.
Use a UIButton instead and simply adjust the image insets until your satisfied (just disable the button or set user interaction to no here to "mimic" an image view)
Create a wrapper method that creates a new image to your desired size. Something like this should work just fine
CGSize size = CGSizeMake(< some width > , < some height >);
Then just create a new image capture with the size you've chosen
CGFloat scale = MAX(size.width/image.size.width, size.height/image.size.height);
CGFloat width = image.size.width * scale;
CGFloat height = image.size.height * scale;
CGRect imageRect = CGRectMake((size.width - width)/2.0f,
(size.height - height)/2.0f,
width,
height);
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
[image drawInRect:imageRect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
From here you should then be able to just apply a border width and color to get your desired result!
I guess a fourth (4th) option could be manually shrinking the image (with some photo editor) so that it renders (fits) into your image view with the appropriate padding around the image. I think the others are easier and best practice though.

set UIImageView to display middle section of an image

I've got an image view that I want to show a central slice of the user's profile picture. I want to scale the picture so that the width matches the width of the screen while maintaining the aspect ratio, center the image, and then have any extra on the top/bottom to not appear at all.
I've tried setting the imageView.contentMode to UIViewContentModeScaleAspectFill, UIViewContentModeScaleAspectFit, UIViewContentModeCenter and a few others, but it either resizes my UIImageView, changes the aspect ratio, or doesn't fill the area.
"but it either resizes my UIImageView"
I guess you see the cropped parts.
Maybe you forgot the "clipsToBounds" property?
UIImageView *view1 = [[UIImageView alloc] initWithFrame: ___ ];
view1.clipsToBounds = YES;
UIImage * img = [UIImage imageNamed:#" ___ "];
view1.image = img;
view1.contentMode = UIViewContentModeScaleAspectFill;

Is there a way to auto-size a UIImageView in Interface Builder/storyboard?

When you set a image for a uiimageview in storyboard or interface builder, it retains the shape of the original UIImageView, which means that the image itself is completely distorted.
To match the size of the UIImageView to its image, I have to manually enter in the size from the file inspector.
Is there a way that UIImageView can automatically detect the native size of its image and size its self accordingly?
I am assuming you are referring to layout in storyboard/IB. To get the native size of the image just select the image and press Command + = on the keyboard. the to re-size it proportionally select the corner and hold down the shift key when you re-size it.
Why don't you set the size of your uiimageview in code?
Here's what you need to do...
//get the Image
UIImage *img = [UIImage imageNamed:#"img.png"];
CGFloat x = img.origin.x;
CGFloat y = img.origin.y;
CGFloat width = img.size.width;
CGFloat height = img.size.height;
imageView.frame = CGRectMake(x, y, width, height); //imageView is your uiimageview's reference
Use the contentMode
 imageView.contentMode = UIViewContentModeScaleAspectFit;
Edit :
I just saw you seem to want to adjust imageViews size to the image.... Different then
This is what I did:
imageView.clipsToBounds = YES;
[imageView setContentMode: UIViewContentModeScaleAspectFit];
That is working for me.

Problems scaling a UIImage to fit a UIButton

I have a set of buttons and different sized images. I want to scale each image in order that it fits the button in the correct aspect ratio. Once I've scaled the image, I set the button's image property to the scaled version.
UIImage *scaledImage = [image scaledForButton:pickerButton];
[pickerButton setImage:scaledImage forState:UIControlStateNormal];
my scaledForButton method is defined in a class extension for UIImage. It looks like this:
- (UIImage *)scaledForButton:(UIButton *)button
{
// Check which dimension (width or height) to pay respect to and
// calculate the scale factor
CGFloat imageRatio = self.size.width / self.size.height;
CGFloat buttonRatio = button.frame.size.width / button.frame.size.height;
CGFloat scaleFactor = (imageRatio > buttonRatio ? self.size.width/button.frame.size.width : self.size.height/button.frame.size.height);
// Create image using scale factor
UIImage *scaledimage = [UIImage imageWithCGImage:[self CGImage]
scale:scaleFactor
orientation:UIImageOrientationUp];
return scaledimage;
}
When I run this on an iPad2 it works fine and the images are scaled correctly. However if I run it on a retina display (both in the simulator and on a device) the image does not scale correctly and is squished into the button.
Any ideas why this would happen on retina only? I've been scratching my head for a couple of days but can't figure it out. They're both running the same iOS and I've checked the scale and ratio outputs, which are always the same, regardless of device. Many thanks.
Found the answer here: UIButton doesn't listen to content mode setting?
If you're setting the .contentMode, it seems you have to set the imageView property of the UIButton, not just the UIButton, then it worked properly.
The problem on iPad 3 was as Herman suggested - the CGImage was still a lot larger than the UIButton, so even though it was scaled down, it still had to be resized to fit the button.

How do I pan the image inside a UIImageView?

I have a UIImageView that is displaying an image that is wider and taller than the UIImageView is. I would like to pan the image within the view using an animation (so that the pan is nice and smooth).
It seems to me that I should be able to just adjust the bounds.origin of the UIImageView, and the image should move (because the image should paint inside the view with that as its origin, right?) but that doesn't seem to work. The bounds.origin changes, but the image draws in the same location.
What almost works is to change the contentsRect of the view's layer. But this begins as a unit square, even though the viewable area of the image is not the whole image. So I'm not sure how I would detect that the far edge of the image is being pulled into the viewable area (which I need to avoid, since it displays by stretching the edge out to infinity, which looks, well, sub-par).
My view currently has its contentsGravity set to kCAGravityTopLeft via Interface Builder, if that makes a difference (Is it causing the image to move?). No other options seemed to be any better, though.
UPDATE: to be clear, I want to move the image inside the view, while keeping the view in the same spot.
I'd highly recommend enclosing your UIImageView in a UIScrollView. Have the UIImageView display the full image, and set the contentSize on the UIScrollView to be the same as your UIImageView's size. Your window into the image will be the size of the UIScrollView, and by using scrollRectToVisible:animated: you can pan to particular areas on the image in an animated fashion.
If you don't want scroll bars to appear, you can set the showsHorizontalScrollIndicator and showsVerticalScrollIndicatorproperties to NO.
UIScrollView also provides pinch-zooming functionality, which may or may not be useful to you.
Brad Larson pointed me down the right road with his suggestion to put the UIImageView inside a UIScrollView.
In the end I put the UIImageView inside of a UIScrollView, and set the scrollView's contentSize and the imageView's bounds to be the same size as the image in the UIImage:
UIImage* image = imageView.image;
imageView.bounds = CGRectMake(0, 0, image.size.width, image.size.height);
scrollView.contentSize = image.size;
Then, I can animate the scrollView's contentOffset to achieve a nice panning effect:
[UIView beginAnimations:#"pan" context:nil];
[UIView setAnimationDuration:animationDuration];
scrollView.contentOffset = newRect.origin;
[UIView commitAnimations];
In my particular case, I'm panning to a random space in the image. In order to find a proper rect to pan to and a proper duration to get a nice constant speed, I use the following:
UIImage* image = imageView.image;
float xNewOrigin = [TCBRandom randomIntLessThan:image.size.width - scrollView.bounds.size.width];
float yNewOrigin = [TCBRandom randomIntLessThan:image.size.height - scrollView.bounds.size.height];
CGRect oldRect = scrollView.bounds;
CGRect newRect = CGRectMake(
xNewOrigin,
yNewOrigin,
scrollView.bounds.size.width,
scrollView.bounds.size.height);
float xDistance = fabs(xNewOrigin - oldRect.origin.x);
float yDistance = fabs(yNewOrigin - oldRect.origin.y);
float hDistance = sqrtf(powf(xDistance, 2) + powf(yDistance, 2));
float hDistanceInPixels = hDistance;
float animationDuration = hDistanceInPixels / speedInPixelsPerSecond;
I'm using a speedInPixelsPerSecond of 10.0f, but other applications might want to use a different value.