Unexpected NSLayoutConstraint behaviour in IOS7 - ios

I am getting this issue, only in iOS versions prior to 8
The selected view in the very first screen shot is a UIImageView. you can also see the constraints i have connected. I need to make the image view circular, so i am using layer.cornerRadius property. normally for circular UIImageView we use cornerRadius = height/2.0
but when i am setting this property in "viewDidLayoutSubviews" method. some how its giving me a square imageview.
as you can see i have set aspect ratio of image 1:1
so it can be turned into circular UIImageView.
I know I must be missing out some facts about NSLayoutConstraints. please help me out
My Code :-
-(void)viewDidLayoutSubviews
{
float height = profile_InfoSubView_ProfilePic.bounds.size.height;
float width = profile_InfoSubView_ProfilePic.bounds.size.width;
NSLog(#"(w,h)= %0.0f , %0.0f",width,height);
float cr = height/2.0;
profile_InfoSubView_ProfilePic.layer.cornerRadius = cr;
profile_InfoSubView_ProfilePic.layer.masksToBounds = YES;
profile_InfoSubView_ProfilePic.layer.borderWidth = 2.0f;
profile_InfoSubView_ProfilePic.layer.borderColor = [UIColor greenColor].CGColor;
}
Console Output
2015-09-08 10:42:35.156 MyApp[821:60b] (w,h)= 240 , 128
as you can see even after setting image aspect ration to 1:1, its not square
Output On Device (iPhone 4 - iOS 7.1 )

Related

UIImage in self sizing UITableViewCell stretching

So I have a tableview setup so it displays some information text with an image, the text can vary so I've set up the constraints that the cell updates its size by itself, however the images are stretching as shown below and i've checked that the content mode is set to Aspect Fit.
As it can be observed from the image there are 3 Views in the cell:
-The Title
-The Image, which is being stretched
-The description
My constraints are set up as followed:
Title.top = topMargin
Title.trailing = trailingMargin
Title.leading = leadingMargin
Title.height = 32
Image.leading = leadingMargin
Image.top = Title.bottom + 16
bottom.margin = Image.bottom
Image.width = SuperView(content of cell).width * 0.4
text.leading = image.trailing + 16
trailingMargin = text.trailing
bottomMargin = text.bottom
text.top = topMargin + 16
How can I fix this issue so the images don't stretch? If any additional information is needed please ask and i'll add it.
Thanks
-Jorge
Add a height constraint to the image matching its width so that it maintains its square aspect ratio. Or any height for that matter. Just fix the height so that it does not stretch.
image.height = SuperView(content of cell).width * 0.4
For an app I just created, the tableViewCells and images exhibited something similar, stretching after the cell was scrolled off screen and back into view.
Assuming the image is retrieved from a server (or a file with image data), create a UIImage with a scale factor before setting it as the image of the UIImageView in the tableViewCell. I experimented with a few scale factors (instead of calculating, so your results may vary) before setting it as 5... it is better to calculate for production code but in prototyping, this heuristic worked:
UIImage* scaledImage = [[UIImage alloc] initWithData:data scale:5.0f];
// ... On MainThread
[cell.imageView setImage:scaledImage];

How to get a circle image in UIImageView

I tried to get a circle image using layer, here is my code
_compassArrow.layer.cornerRadius = _compassArrow.frame.size.width / 2;
_compassArrow.layer.masksToBounds = YES;
_compassArrow.layer.borderColor = [UIColor whiteColor].CGColor
the compassArrow is an imageview which display the compass image. And when I run my program, it looks terrible:
my actual picture
I don't know what happened to it. I've add some constraints to it, to make it has equal width with the device. Does this influence my image?
I think you set cornerRadius before your constraints are applied. Try to put this code in layoutSubviews or viewDidLayoutSubviews for example.
This way, the _compassArrow.frame.size.width value will be the one after constraints applied on it, and you'll get the correct cornerRadius.
Here is a piece of code that should allow you to do this.
_compassArrow.layer.borderWidth = 1.0
_compassArrow.layer.masksToBounds = false
_compassArrow.layer.borderColor = UIColor.whiteColor().CGColor
_compassArrow.layer.cornerRadius = profilePicture.frame.size.width/2
_compassArrow.clipsToBounds = true

How to add image as in circular frame in ios [duplicate]

This question already has answers here:
image in circle frame iOS [closed]
(2 answers)
Closed 6 years ago.
In my app i want show image of the caller in circular frame. How to change image view from rectangular frame to a circular one. It should also fit the caller image!
You can use corner radius property like,
self.imageViewProfile.layer.cornerRadius = 26.5;
self.imageViewProfile.layer.masksToBounds = YES;
Corner radius should be half of the height and width of imageview & height and width should be equal of imageview (i.e. height = width).
By this setup you will able to get rounded imageView.
and maskToBounds set your image as per shape of rounded imageView
Hope this will help :)
Image should be equal height and equal width than you can create circular image.
yourImageView.layer.cornerRadius = yourImageView.frame.size.height /2;
yourImageView.layer.clipToBounds = true;
I think it would be help full for you.If you have any issue plz let me know.
Please try this code it works for you
cell.imageView.layer.cornerRadius = cell.imageView.frame.size.height /2;
cell.imageView.layer.masksToBounds = YES;
cell.imageView.layer.borderWidth = 0;

Make an UIImageView and its UIImage scale proportionally without extra padding

I have an UIView that contains a UIImageView. The UIImageViews works like the branding logo of the app. When I rotate the device, the containing UIView resizes itself to correspond to the landscape or portrait proportions of the screen.
What I'm trying to achieve is to have the UIImageView scaled accordingly, keeping proportions also on the left margin.
This is the actual code for the top white "banner":
UIView *topBanner = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, height_topBanner)];
[topBanner setAutoresizingMask:(UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin)];
[topBanner setBackgroundColor:[UIColor whiteColor]];
topBanner.autoresizesSubviews = YES;
// the logo
UIImage *topBanner_logo = [UIImage imageNamed:#"logo.png"];
float logoAspectRatio = topBanner_logo.size.width/topBanner_logo.size.height;
topBanner_logoView = [[UIImageView alloc] initWithFrame:CGRectMake(topBanner.frame.size.width/100*3, topBanner.frame.size.height/100*7, (topBanner.frame.size.height/100*86)*logoAspectRatio, topBanner.frame.size.height/100*86)];
[topBanner_logoView setImage:topBanner_logo];
topBanner_logoView.backgroundColor = [UIColor blueColor];
topBanner_logoView.contentMode = UIViewContentModeScaleAspectFit;
[topBanner_logoView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleBottomMargin|UIViewAutoresizingFlexibleRightMargin)];
[topBanner addSubview:topBanner_logoView];
[self.view addSubview:topBanner];
This is my starting point: portrait iPad on startup:
This is what happens when I rotate it in landscape:
As you can see, the proportions of the UIImage are ok, but I'm getting extra borders (I set the background color of the UIImageView to highlight it) because the UIImageView stretches itself to follow the change of the size of its container, and the UIImage is fit into the UIImageView and put on its center.
The same - reversed - happens when I start the app directly in landscape mode:
Then I rotate it:
... and I get the logo with extra borders on top and bottom.
I do see that I can write a function to recalculate every size on each rotation change, but I'm asking to myself if is there a way to set the UIImageView and the UIImage to make it works without hacking the autorotate/resize procedures of iOS. It sounds so simple!
You can solve this by not using UIViewContentModeScaleAspectFit, and instead calculating the aspect ratio of the image and using that to explicitly the width or height based on the other (width or height).
e.g. I rotate to landscape, and so I want the height to be 80% of the view.
CGFloat w = logo.image.size.width;
CGFloat h = logo.image.size.height;
CGFloat a = w / h;
CGFloat h_use = self.view.height *0.8;
CGFloat w_use = h_use*a;
Furthermore, set the content mode to UIViewContentModeScaleAspectFill instead now that you've explicitly set the aspect ratio.
You have set the auto resizing mask to flexible height and width:
[topBanner_logoView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleBottomMargin|UIViewAutoresizingFlexibleRightMargin)];
If you do not do that, the default is that the view will not chance size, and therefore, the image will not either.
I think it is because of topBanner_logoView.contentMode = UIViewContentModeScaleAspectFit;
Try topBanner_logoView.contentMode = UIViewContentModeCenter or topBanner_logoView.contentMode = UIViewContentModeLeft to prevent the UIImageView's image from resizing (and getting padding).
If the UIImageView is resizing, remove the autoresizing mask.

Resize UILabel correct on top of UIImageView

My problem is as follows:
I have on top of a UIImageView some labels. The image is a formular and the UILabels represents the entries.
If I rotate the device the image inside UIImageView gets resized with option "aspect fit".
How can I achieve that the UILabel is also resized and aligned correct?
The normal options for resizing aren't working as needed.
The UIImageView is zoomable with minimumZoomScale and maximumZoomScale set.
Thanks.
You can resize a UILabel proportionally using:
label.transform = CGAffineTransformMakeScale(0.5, 0.5);
You can reposition a UILabel relatively using:
label.frame = CGRectOffset(label.frame, deltaX, deltaY);
The rest is maths =)
So I managed to solve your problem. Full source code here.
Basically I removed your UIImageView and replaced it with a UIView. Then I added your UILabels within the UIView and removed any autosizing from the UIView and UILabels in interface builder. That way when the UIView gets resized any content in it will get resized/repositioned as well.
The next step was to change the class of the UIView to UIImageView in interface builder. Now from the source code I could set an image to it using imgView.image = [UIImage imageNamed:#"imagename.png"]; as well as I could set the mode using imgView.contentMode = UIViewContentModeScaleAspectFit;.
The transformation at rotation now happens with:
if (UIDeviceOrientationIsLandscape(deviceOrientation)){
// Play with the scale if you have any other images with different ratio.
float scale = 2.3f/3.0f;
// Transforming the UIImageView containing the UILabels which actually is a simple UIView
imgView.transform = CGAffineTransformMakeScale(scale, scale);
} else {
// Original size again
imgView.transform = CGAffineTransformMakeScale(1, 1);
}

Resources