UIImageView ignores changes in contentMode - ios

I'm absolutely stumped with this sizing bug I have. I have a UIImageView and a UITableView in my view layout. The UIImageView is set to Aspect Fit in IB, and it behaves as I want it to when i set the image using IB. but when I set the image programmatically, it resizes the view incorrectly.
I've tried everything I can think of to get this to appear correctly in the simulator and nothing comes out right.
bannerView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
bannerView.contentMode = UIViewContentModeScaleAspectFit;
bannerView.image = banner;
bannerView.frame = CGRectMake(0,0,320,80);
bannerView.contentMode = UIViewContentModeScaleAspectFit;
self.tableView.frame = CGRectMake(0,80,320,380);
Now the really interesting thing is that even though by the way I am constructing their frames, the tableview in this code should be directly below the image view. In reality, it is not. The table view doesnt move from where I had placed it in IB (with that exact frame size and coordinates), but the image view is way smaller for some reason.
Pleas help, this doesn't make any sense to me why this doesn't work

Ok, it seems the problem was in IB I had in the autosizing section for the view, all of the arrows were checked, when I only needed the top and left ones checked to keep it aligned

Related

How to make sure the image is allways positioned to the top?

I use UIImage to display my test image with Aspect Fit mode. I want it to be always positioned to the top and fill as much space as it can (see image below).
How to setup constraints, so that the image will be always positioned to the top (without any gap on taller devices)?
Additional info:
I'm using Xcode 7.0.1
Developing for iOS 8 and above.
I'm using auto layout.
I've tried to set " >= 0" to the bottom constraint, so that the bottom gap could get a double height, but it didn't work.
Any suggestions?
I suggest you programmatically calculate the size of the imageView and set the frame directly.
Do so in your viewWillAppear or viewDidLoad method of your viewController.
this will do the trick
UIImage *image; // yourImage
CGFloat whRatio = image.size.width/image.size.height;
if (whRatio > 1) {
// there will be borders on top -> adjust your view
imageView.frame = CGRectMake(imageView.frame.origin.x,
imageView.frame.origin.y,
imageView.frame.size.width,
imageView.frame.size.height / whRatio);
}
You might want to think about also adjusting the imageView in case the image is narrow, to prevent white spaces completely.
I think you have the correct constraints. Did you try to set the contentMode to "Scale to fill".
maybe you are using aspectFit
Here I'm adding an image showing how constraints are setup for the view that contains the image, as well for the image inside the view.
If anyone want to look at my experiments in details I've made a public repo via the link below. It includes the storyboard solution branch as well as code solution branche.
https://bitbucket.org/AndrejBB/test-layout

UIImageView overflowing custom tableview cell

I have a custom table view cell with a UIImage on the left, and two labels on the right one on-top of the other. I originally had only the image and one label, and the image was fitting perfectly inside the cell, but after I added the second label, the table view cell is smaller and doesn't contain the full image(even though the image is still the same size as it was), and doesn't contain the second label. So for some reason after I added the second label the custom tableview cell shrunk in heigh and won't contain them. I have messed with constraints for hours and can't seem to find the right ones. And yes, the image is aspect fit.
Let me know your thoughts, this might be a simple fix, I just simply can't find that fix. Thanks in advance!
When you click on your UIImageView, ensure that it has Mode set to "Scale To Fill" In the attributes inspector. It can be done programatically like this if you want:
newImgThumb.contentMode = .ScaleAspectFit
Also, make sure that your constraints are not conflicting and are properly arranged. If this doesn't work post some screenshots and I will take another crack.
Set mode of image view Aspect Fill, and select Clip Subview in XIB/Storyboard.
Hopefully it works. Thanks

UIImageView inside custom UITableViewCell - shows a little distorted image

I'm using UITableView with custom cells to create my own selection table.
Each cell has its own UIImageView, it's pinned to the right side of cell and there are three constraints on it: right trailing, top and bottom are pinned to these of the superview.
The image I use to show has template render style, there are 3 different sizes for different screen resolutions (16x16,32x32 and 48x48).
Everything works just fine, except one little quirk: the displayed image seems to be shifted up for one or two pixel lines, and these lines are added to the bottom of the image (at least it looks like that).
The view mode is set up as "Center", I tried others, but all modes that do not scale the image (I just want it to show as it is) have the same quirk.
I tried everything I could think of, but no success - the quirk's still here. In the Xcode view hierarchy everything shows just perfect! No quirk!
Has anyone seen anything similar? Are there any secret magic actions to avoid such an effect? My head explodes :(
Here are the screenshots: https://yadi.sk/d/rtTqVqcYfPJB3
In storyboard you want to set the UIImageView mode to either aspect fit or aspect fill.
Aspect Fit: fits your image proportionally inside the UIImageView so you might end up with white space
Aspect Fill: fills the UIImageView with you image proportionally but you might have some overflow that cuts off part of your image
You can also do this programmatically:
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.contentMode = UIViewContentModeScaleAspectFill;
I have fixed the quirk by one (quite straightforward) step: by adding two blank lines, one line to the top, one line to the bottom of the icon.
So resulting icon sizes in my case: 16x18, 32x34, 48x50. The quirk is gone totally, but the reason for this weird behavior is still unknown for me.

subView not animating properly when main View shrinks

My app has a UIView called stepView that needs to grow and shrink, always expanding down and to the right, and always shrinking up and to the left. It has a subview, durationLabel, which runs along the entire width of the stepView and has a fixed height.
When the stepView is animated to grow larger, the label grows properly along with it: the text and the label's background slide to the right in sync with the growing stepView. However, when the stepView is animated to grow smaller, it immediately snaps to its new size, leaving a gap between the stepView's shrinking right edge and its right edge until the animation completes.
The label initialization code in stepView.m:
CGRect duration_frame = CGRectMake(0, 0, self.frame.size.width, HEADER_HEIGHT);
self.durationLabel = [[UILabel alloc] initWithFrame:duration_frame];
[self.durationLabel setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
[self addSubview:self.durationLabel];
And the animation code:
[UIView animateWithDuration:ANIM_DURATION
animations:^{
[stepView setFrame:newFrame];
}
];
Using bounds/center instead of frame produces the same effect. I've considered using a transform instead, but the code for calculating "newFrame" is somewhat involved, so I'd rather avoid rewriting it if possible. I've also tried manually changing the label's frame in the same animation block, but that simply makes it disappear entirely (possibly because I was trying to animate both a view's frame and its subview's frame in the same animation block?). I've also confirmed stepView and its subviews aren't undergoing any other animations at the same time, although there are animations happening to unrelated views in separate animation blocks.
I'm at a loss for why the label should animate perfectly when the stepView grows but fail to animate at all when it shrinks. I haven't seen anything in the documentation that indicates there would be a difference. Thank you for any help you can provide.
I think this is an issue with UILabel - using another UIView as subview instead of an UILabel the animation works fine also when you shrink.
If I understand correctly what you need to obtain as result, however, I would suggest you to try the following:
don't set the autoresizingMask property
// [self.durationLabel setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
set the stepView clipToBounds property to YES
self.clipToBounds = YES;
This way the UILabel frame will not change but only the part which is actually within the stepView bounds will be visible. I hope this might help.
Update: just done a quick research and found that the question is already answered here resize uiview with UILabel and animate it correctly - the answers provided seem to be aligned to what I've suggested above.

Auto Layout keeps stretching UIImageView

I am using Auto layout and it's driving me crazy. I have done everything I could to prevent UIImageView from stretching all over. I have no idea why it does that. I tried using constraints, solving auto layout issues. For now, the only solution was turning the auto layout itself.
Could anyone please tell me why xcode is completely ignoring my constraints? I would expect the UIImage to stay as 320x320 when I explicitly set it as that, but noooooooo....
I want to post images, but the site won't let me, and I would like to add code to this question so that it is more specific, but there's literally no code at all. I just dragged "UIImageView" from storyboard, made it small, set constraints as is, and it's just ignoring my code.
You'll want to make sure your UIImageView is set to clip to bounds. If not, the image will spill out of the view and will appear to not stretch correctly (even though in reality it is).
In interface builder, make sure the Clip Subviews box is checked.
If you're not using interface builder, the following code will do the same thing:
yourImageView.clipsToBounds = YES;
With autolayout, the values in the Size Inspector are pretty much ignored.
You might expect that if a number is typed into the boxes on the Size Inspector, Xcode would automatically create constraints to reflect what you typed, but it doesn't. You need to create "Pin" constraints on your own for the height and width of your UIImageView.
Select the image view on your storyboard
Click the "Pin" button at the bottom-right of the storyboard screen
Type the desired size into the "Width" and "Height" fields, and make sure the boxes are checked
Click the "Add 2 constraints" button
When you are done, you should be able to see your constraints in the Size Inspector on the right side of the screen (the purple boxes)
My problem was with the ContentHuggingPriority and ContentCompressionResistancePriority.
The first controls how important it is to keep the view "hugging" the image (staying close to it and not expanding) and the latter controls how resistant to compression the view is.
We use PureLayout, so the code to fix it was:
[NSLayoutConstraint autoSetPriority:ALLayoutPriorityRequired forConstraints:^{
[myImageView autoSetContentCompressionResistancePriorityForAxis:ALAxisHorizontal];
[myImageView autoSetContentHuggingPriorityForAxis:ALAxisHorizontal];
}];
(my problem was only in the horizontal axis)
May 15, 2016: Updated to PureLayout v3 syntax. If you use a version <= 2 just put UIView instead of NSLayoutConstraint. Thanks Rudolf J!
I had the same problem. I added a UIImageView into a prototype cell and wanted to align it next to the text but it kept stretching the image when I applied the constraints. In my case, I changed the 'Mode' property for the Image View to 'Aspect Fit' and it worked fine.
You can try to add UIImageView programmatically.
Call this code in your viewDidLoad method or where you want.
UIImageView *yourImageView = [[UIImageView alloc]initWithFrame:CGRectMake(50.0f, 50.0f, 320.0f, 320.0f)]; // x and y coordinates, width and height of UIImageView
[yourImageView setImage:[UIImage imageNamed:#"your_image.png"]];
[yourImageView setContentMode:UIViewContentModeCenter]; // you can try use another UIViewContentMode
[self.view addSubview:yourImageView];

Resources