UIViewContentModeScaleAspectFit doesn't work - ios

I try to scale my image and i want use Aspect Fit. But it doesn't work
solutionImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"bg_solution#2x.png"]];
// optional:
solutionImageView.contentMode = UIViewContentModeScaleAspectFit; // content mode
solutionImageView.center = CGPointMake((currentWidth)/2, currentHeight - (currentHeight/3.5));
[self.view addSubview:solutionImageView];

As arunit21 said in his comment, when you create an UIImageView with the initWithImage method, the size of frame of the view is calculated with image size. So your image view is centered but bigger than you window.
You can do
solutionImageView = [[UIImageView alloc] initWithFrame:yourFrame];
solutionImageView.image = [UIImage imageNamed:#"bg_solution"];
solutionImageView.contentMode = UIViewContentModeScaleAspectFit; // content mode
solutionImageView.center = CGPointMake((currentWidth)/2, currentHeight - (currentHeight/3.5));
[self.view addSubview:solutionImageView];
You can also just set your new frame after your initialization to set the correct size.
The #2x.pngis not needed in [UIImage imageNamed:#"bg_solution"]. With this method, the system will check if the screen is retina and look for the #2ximage if it exists and take the normal one otherwise.

Related

Loading Remote images in TableView while keeping sizes intact

I want to show a table view where each cell will just contain one image. Images are loaded from respective URLs and there is no restriction on the size of the image.
I want to show the image in each cell with their proper sizes - that is maintain the aspect ratio. I am guessing this would entail having dynamic heights for each cell. But I am not sure and can't find a resource which explains how to achieve this.
What would be the best way to do this?
You need to get the image height and width dynamically first and set the same hieght and width to your table view cells.
I have not added table view but just some code will help you see how you can show two different images with their original height and width and adding the same to a view.
NSURL *imageURL1 = [NSURL URLWithString:#"http://cdn.macrumors.com/article-new/2014/12/applelogo.png"];
NSData *imageData1 = [NSData dataWithContentsOfURL:imageURL1];
UIImage *image1 = [UIImage imageWithData:imageData1];
UIImageView *imageView1 = [[UIImageView alloc] initWithImage: image1];
//CGFloat height = imageView.frame.size.height;
//CGFloat width = imageView.frame.size.width;
[self.view addSubview:imageView1];
//sample urls :- http://pre01.deviantart.net/e711/th/pre/f/2013/179/2/c/ios_7_icons__updated__by_iynque-d69mme1.png
NSURL *imageURL2 = [NSURL URLWithString:#"http://icons.iconarchive.com/icons/position-relative/social-2/128/ios-icon.png"];
NSData *imageData2 = [NSData dataWithContentsOfURL:imageURL2];
UIImage *image2 = [UIImage imageWithData:imageData2];
UIImageView *imageView2 = [[UIImageView alloc] initWithImage: image2];
CGFloat height = imageView2.frame.size.height;
CGFloat width = imageView2.frame.size.width;
imageView2.frame = CGRectMake(0, 300, width, height);
NSLog(#"height :- %f, Width :- %f ",height, width);
[self.view addSubview:imageView2];
Hopefully, you are loading the images asynchronously, as answered here: Loading images for UITableViewCell from URL (need to load them asynchronously)
You'll need a custom cell or prototype cell with a UIImageView set to UIViewContentModeScaleAspectFit. In the cell, set the constraints how you want them: that is, if you want the image to be the full width of the screen, set leading and trailing constraints, and constrain to the top and bottom.
Then, set your table view to use dynamic sizing:
tableView.estimatedRowHeight = 80.0; //or some reasonable first approximation
tableView.rowHeight = UITableViewAutomaticDimension;

I need to make my UIImageView fit inside my UIScrollView without panning. [iOS]

I have an image inside of an iOS UIScrollView that only takes up about 1/3rd of the total screen space. The image is too large, so the scrollView is allowing panning around the image. I want the image to be small enough so that there is no panning necessary to see the entire image. How do I resize the image to make it fit inside of the scroll view?
This is the code I am using to set up the image view and the scroll view.
UIImage *image = [UIImage imageNamed:#"banner.png"];
self.imageView = [[UIImageView alloc] initWithImage:image];
self.imageView.frame = (CGRect){.origin=CGPointMake(0.0f, 0.0f), .size=image.size};
[self.scrollView addSubview:self.imageView];
self.scrollView.contentSize = image.size;
You need to set the ImageView's size equal to the scrollView's size. And set the imageView's content mode to scale to fill
Eg:
UIImage *image = [UIImage imageNamed:#"banner.png"];
self.imageView = [[UIImageView alloc] initWithImage:image]
self.imageView.frame = CGRectMake (0,0,self.scrollView.frame.size.width,self.scrollView.frame.size.height);
self.imageView.contentMode = UIViewContentModeScaleToFill;
[self.scrollView addSubview:self.imageView];
self.scrollView.contentSize = self.imageView.frame.size;
self.scrollView.bounces = NO;
You can't not make the frame of imageView as the size of image(since image is too large). Set the frame of imageview as you desired and set image contentmode.
You should probably need to pick right image content mode
self.imageView.contentMode = (Pick right content mode you need)
typedef NS_ENUM(NSInteger, UIViewContentMode) {
UIViewContentModeScaleToFill,
UIViewContentModeScaleAspectFit, // contents scaled to fit with fixed aspect. remainder is transparent
UIViewContentModeScaleAspectFill, // contents scaled to fill with fixed aspect. some portion of content may be clipped.
UIViewContentModeRedraw, // redraw on bounds change (calls -setNeedsDisplay)
UIViewContentModeCenter, // contents remain same size. positioned adjusted.
UIViewContentModeTop,
UIViewContentModeBottom,
UIViewContentModeLeft,
UIViewContentModeRight,
UIViewContentModeTopLeft,
UIViewContentModeTopRight,
UIViewContentModeBottomLeft,
UIViewContentModeBottomRight,
};

iOS: ImageView filled with a picture

I have a table that contains the path to the picture, saved on user's library. Then, I pass this path to a View that contains just a imageView. I want to fills this ImageView with the picture. Like WhatsApp (when you click on a profile's picture). But, my picture it's always cropped or distorted. I tryed different ways to do this, but I didn't find the best way:
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationController.navigationBar.translucent = NO;
UIImage *picture = [UIImage imageWithContentsOfFile: self.picturePath]; //I passed this path from the previous View
UIImageView* imageView = [[UIImageView alloc] initWithImage:picture];
CGRect screenRect = [[UIScreen mainScreen] bounds];
imageView.frame = CGRectMake(0, 0, screenRect.size.width, screenRect.size.height);
imageView.contentMode = UIViewContentModeScaleAspectFill;
[self.view addSubview:imageView];
}
Original (I want something like it)
My app
If your image is cut , the reason is you are using a higher resolution image in a smaller container and instructed your imageview to fill , using this line imageView.contentMode = UIViewContentModeScaleAspectFill;
Change it to imageView.contentMode = UIViewContentModeScaleAspectFit;
I think #whitewolf09 is right and his method will solve your problem. But i suggest you to look into MGImageUtilities that will be very useful for different cases where you can crop images maintaining aspect ratio to fit inside your image view's frame.
Just #import "UIImage+ProportionalFill.h"
UIImage *image = [[UIImage imageWithContentsOfFile:filePath] imageScaledToFitSize:imageView.frame.size];
That's the very useful category for image resizing and may help you in future.
I think the reason it is being clipped is that you are creating the image view with a picture THEN setting the frame and probably the picture is bigger than the frame so it is clipping it. Also try changing the aspect to: 'UIViewContentModeScaleAspectFit' Try this:
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationController.navigationBar.translucent = NO;
UIImage *picture = [UIImage imageWithContentsOfFile:self.picturePath]; //I passed this path from the previous View
UIImageView* imageView = [[UIImageView alloc] initWithRect:CGRectMake(0, 0, screenRect.size.width, screenRect.size.height);];
CGRect screenRect = [[UIScreen mainScreen] bounds];
imageView.image = picture;
imageView.contentMode = UIViewContentModeCenter;
[self.view addSubview:imageView];
}

UIImageView and autolayout

I have a view that is set up nicely using autolayout. The view contains a series of labels stacked from top to bottom. I am allowing the intrinsic size of these labels to determine the size of the view.
The final step is to add a background from an image. I started by trying the colorWithPatternImage method on UIColor but this isn't quite what I am looking for. I do not want to tile the image, and I can not guarantee it will always be larger than the intrinsic size of the view.
Similarly, adding a uiImageView to the view itself doesn't quite work. The view will expand to accommodate the image when I want to keep the intrinsic size based on the labels.
I guess what I am looking for is the following.
1) The background should have no effect on the size of the view.
2) The image should be scaled to fill the view but in it's original aspect ration (so cropping edges if necessary).
Any ideas appreciated.
In my case, I needed it for a UIImageView inside a dynamically-sized view in a UITableViewCell, but the image refused to shrink below its instristic size and instead worked as a minimum-size constraint for the superview. The only way I could get it ignore the intristic size is by lowering the priority at which it is enforced, right after creating the cell:
[imageView setContentCompressionResistancePriority:UILayoutPriorityDefaultLow
forAxis:UILayoutConstraintAxisHorizontal];
[imageView setContentCompressionResistancePriority:UILayoutPriorityDefaultLow
forAxis:UILayoutConstraintAxisVertical];
After this, all my constraints magically started working. In the OP's case, setting UIViewContentModeScaleAspectFill is also required, as per Mundi's answer.
In Interface Builder, add a UIImageView as the first subview to the view. Make sure its size always matches the view.
Then, in Interface Builder or code, set the contentMode:
backgroundImageView.contentMode = UIViewContentModeScaleAspectFill;
Here's how I would approach this. Hopefully it helps. :)
CGRect contentFrame = CGRectMake(0, 0, self.view.frame.size.width, 0); // This will be the frame used to create the background image view.
UIEdgeInsets contentInsets = UIEdgeInsetsMake(20, 20, 20, 20); // The margins by which the labels will be inset from the edge of their parent view.
CGFloat labelHeight = 21;
CGFloat verticalGap = 8; // The vertical space between labels
CGFloat y = contentInsets.top;
int numberOfLabels = 10;
for (int i = 0; i < numberOfLabels; i++) {
CGRect frame = CGRectMake(contentInsets.left, y, self.view.frame.size.width - (contentInsets.left + contentInsets.right), labelHeight);
UILabel *label = [[[UILabel alloc] initWithFrame: frame] autorelease];
// customize the label here
[self.view addSubview: label];
contentFrame = CGRectUnion(contentFrame, label.frame);
y += labelHeight + verticalGap;
}
contentFrame.size.height += contentInsets.bottom;
UIImageView *backgroundImageView = [[[UIImageView alloc] initWithFrame: contentFrame] autorelease];
[backgroundImageView setClipsToBounds: YES];
[backgroundImageView setContentMode: UIViewContentModeScaleAspectFill];
[backgroundImageView setImage: [UIImage imageNamed: #"background_image.png"]];
[self.view insertSubview: backgroundImageView atIndex: 0];

Stopping UIScrollView at specific place while scrolling with pagingEnabled

I have the following code to create a scroll view with additional area at the beginning and the end of the images (50 points).
UIScrollView* scroll = [[UIScrollView alloc] initWithFrame: CGRectMake(0,0,200,100)];
scroll.contentSize = CGSizeMake(400,100);
UIImageView* img1 = [[UIImageView alloc] initWithFrame: CGRectMake(50,0,100,100);
UIImageView* img2 = [[UIImageView alloc] initWithFrame: CGRectMake(150,0,100,100);
UIImageView* img3 = [[UIImageView alloc] initWithFrame: CGRectMake(250,0,100,100);
//Adding images to ImageViews
scroll.pagingEnabled = YES;
[scroll addSubView:img1];
[scroll addSubView:img2];
[scroll addSubView:img3];
The first time I see the view, I will see the additional area on the left (0-50), then the first image (50-150) and then half of the second image (150-200).
When I swipe left, I want to see half of the first image on the right, the second image at the center, and half of the third image on the right.
When I swipe left again, I want to see the third image at center, with half of the second image on the left, and the additional area on the right.
Can it be possible?
It's possible as long as you define everything correctly. Make sure that the assigned content size is equal to the overall size that you wish to scroll through. Make sure that each page size is equal to the scroll view's frame. You can set the clipsToBounds to NO if the frame clips your subviews.
You can do this by adjusting the contentSize of UIScrollView
- (void)addImagesToScrollView{
//An offset from where imageViewStarts
CGFloat xOffset = 50.0f;
CGRect imageViewFrame = CGRectMake(xOffset, 0.0f, 100.0f, 100.0f);
for (NSString *imageName in #[#"image1.jpg",#"image2.jpg",#"image3.jpg"])
{
UIImageView *imageView = [[UIImageView alloc]initWithFrame:imageViewFrame];
UIImage *image = [UIImage imageNamed:imageName];
imageView.image = image;
[self.scrollView addSubview:imageView];
imageViewFrame.origin.x+=imageViewFrame.size.width;
}
CGSize contentSize = self.scrollView.frame.size;
//Content size is calculate from the imageViewFrame and an offset is added to it
contentSize.width = imageViewFrame.origin.x+xOffset;
[self.scrollView setContentSize:contentSize];
}
Source Code
You can scroll to a particular place in the scrollview using the following code
[YOURSCROLLVIEW setContentOffset:CGPointMake(x, y) animated:YES];

Resources