How to prevent UIImageView from resizing with Autolayout - ios

I'm recreating my UI with auto layout and have a navbar across the top and a 2x2 grid of UIImageViews filling the rest of the screen. I put in all the constraints so it maintains this arrangement in any orientation and it's working well when the UIImageViews don't have an image in them. When I programmatically load an image in the UIImageViews, they change size and placement even though I have constraints that should prevent this.
I have all the autoresizing masks off for everything and the UIImageViews set to Aspect fit.
This autolayout stuff is new to me, but I thought I had it working...until I put an image in there. Why would that change the size and placement of the UIImageViews?
Thanks for the help!

You can modify contraints at runtime if you link them with an outlet in your view controller.
For your case you would add a width and height constraint and link them to two outlets.
Then after you know the image dimensions you would change the constant value.
I am describing this in detail for a similar use case I had here: http://www.cocoanetics.com/2012/11/first-good-auto-layout-use-case/

Related

UIImageView making other Views inconsistent

I've designed a ViewController with an ImageView, 3 Label-TextField combination, one single Label and one Toolbar at the bottom of the view. All of these view elements are inside a Stack View. The design is like below:
The contentMode property of the ImageView is set to Aspect Fit in the Attributes Inspector.
Now when I run the app and select different size of photos, the ImageView seems to be inconsistent different times. Like:
The teal color background the ImageView is set to distinguish the difference between the ImageView and the original Background.
This is okay. But when I choose a large size photo it seems to be inconsistent as the ImageView is overlapping the Toolbar below and this time the Camera button is no more clickable. Here is the image:
And the design gets more broken when I choose another photo. The view is showing up differently in different times. Screenshots are: and
Now what to do? I haven't done any of these design from the code side, all from the Interface Builder.
Any help will be appreciable.
I have these options in the Drawing section of Attributes Inspector:
And this is my Stack View's attributes:
Well it seems everything is fine. Just add height constraint in your Toolbar. The problem will be fixed.
First, make sure you've checked Clip To Bounds property of UIImageView in Attributes Inspector.
Second, set your constraints and / or Stack View's Distribution property in such way that all your views fits within available height.
Here's a sample: https://www.dropbox.com/s/5a7r0oz1v8vclgz/AspectFitImageView.zip?dl=0
By searching a lot of ways around, I finally was able to sort out the issue. Setting the content hugging priority(don't want to grow) and content compression resistance priority(don't want to shrink) helps a lot. Basically I needed to adjust the elements vertically. So tuning the vertical priorities for each element solved my problem. As I have to keep the size of the ImageView to be changed from time to time I've made it's vertical hugging and compression to lower than the other elements of the Stack View. Other priorities are kept as they were by default.
To visualise the situation, here is attached images. Color combinations are used here to distinguish among the elements of the Stack View.
Hope this helps.

Constraints in ios

I am learning constraints and spent whole day applying them to the following screen.It is not getting displayed properly in landscape mode.Basically i am not getting how to fix vertical space between ,say, label-Welcome to BBBB and textfield-username so that textfield always appears below the label yet the spacing between them is adjusted according to the screens of different size. If i go for Pin\Vertical space, it automatically fixes the constant value.
Remove the label (or just move it out of the way).
Fill the space that you want to resize with a view.
Constrain this view to the objects above and below and to the sides of the parent view.
Put your label into this view and constrain it to the top of this view and centred to it.
You may need to change the constraints on the objects above and below it to stop them from changing height in an unwanted manner.
This new view should now resize as the device changes orientation but the label should remain at the top of it.
Repeat on other areas of your layout (i.e put things that are not moving around as you want them into sub views and constrain these views to resize accordingly). Experiment with using variable heights, fixed heigh constraints and 'equal heights with' constraints on the views that you add to get them to resize as you need.
Edit: but you have a lot of vertically stacked items in that view - you may never get them all to fit into a horizontal orientation. You may need to remove a few, or add a scroll view or force that view only to layout in portrait mode or... Don't forget to check that it works on all devices you are targeting.
#Ali Beadle was right. Since i had a lot of vertically stacked items, lining them up in landscape mode was not possible. So, i went for scrollview.
I have taken a ScrollView first and then a UIView named ContentView on that ScrollView. I have made the width of ContentView equal to the width of parent UIView and kept its height fixed to 568. In my code i set
_contentViewHeight.constant = self.view.frame.size.height;
Now it scrolls in landscape mode while in potrait mode, it does'nt scroll.
I run into Autolayout problems all the time. But I finally figured out a way to overcome a lot of issues that arise from it.
I simply will use a container-View like ScrollView or even a plain old UIView, place all my controls in it. thats it. this makes things a lot easier for autolayout to figure out the constraints. in your case you could just use a UIView.
-start off by removing all the constraints you have I would start by selecting each control in the XIB and see if it has width/height constraint, select it then press the delete key then at the bottom of the project explorer you'll see all the constraints that auto layout has select each one then delete. that should get rid of any complaints that auto-layout might have.
-Place a UIView object inside your main View then
-move all the controls inside it. Then
-add the necessary constraints for the container view so it'll resize in different orientations and don't worry about any constraints inside the container view (auto layout will figure them out automatically).
that does the trick for me usually.

iOS 7 Autolayout doesn't work

I've been working today on this problem for a while now and i couldn't solve it. I downloaded Apple's Autolayout Guide and couldn't find an answer/solution. The problem is that I'm adding a UIImageView to my View Controller and when I change the windows form factor from 3.5 to 4 and vise versa, the image view is stretched.
To solve this, I tried many ways such as clicking on reset to suggested constraints, clear all constraints, and build my own constraints by pinning and aligning.
By aligning and pinning I set the height and width to the size as in the Interface Builder and the horizontal and vertical positions as well. Unfortunately, the image still stretches upon changing the form factor in Interface Builder. I tried to only pin the height of the UIImageView but it doesn't work.
How can i work this out?
Autolayout only deals with the frame/bounds of the UIImageView. The actual way the image is rendered is controlled via it's contentMode property. You need to set it to either UIViewContentModeScaleAspectFit or UIViewContentModeScaleAspectFill to avoid stretching.

Resizing a UITextView in UIScrollView using Auto Layout issue

I really hate to ask here because I usually try to figure things out on my own. But on this one I've stuck for days and can't find a solution anywhere online.
I have a ScrollView containing multiple subviews. I've got an image view and two labels at the top with fixed heights. Then there is a UITextView and another ImageView (see pictures).
I add the text to the text view programmatically so it should have a dynamic height and the ImageView should move to the bottom so you can scroll. I don't want the TextView to be scrollable in itself but I want all the subviews to move as well.
I know I should be able to solve this issue using constraints. But I feel like I've tried everything and nothing worked yet. It worked when I disabled auto layout and moved the views manually. I'm wondering if there is a better way though.
As you can see I pinned the TextView to the ImageView above with a 1,000 priority and to the ImageView below with a 1,000 priority. The height constraint can not be deleted so I set it to the lowest possible priority. The ImageView on the bottom is pinned to the bottom of the superview with an absolute height. Its height constraint also has low priority. (I can post an image of the ImageView's constraints, if it helps)
I also tried adapting the frame programmatically but this is not working well in combination with auto layout. (If it helps I can of course post the code)
What am I doing wrong? Shall I just disable auto layout and do it manually? This seems unclean to me. Is it even possible to do?
I really appreciate your help :)
Greets,
Jan
Make sure the Scrolling Enabled attribute on the UITextView is unchecked in Interface Builder. I believe that the Auto Layout system takes that into account when it calculates the intrinsic content size.
If somebody is struggling with a similar problem: This is what I ended up doing:
Remove all subviews from the ScrollView in IB
Programmatically add a single UIView to the ScrollView.
Add all the views to the UIView as subviews (move them using setFrame)
Set the Frame of the UIView appropriately to the subviews
Set the ScrollView's contentSize to the size of the UIView.
A little more work but it finally works. This follows Apple's mixed approach guidelines that can be seen here (look for UIScrollView): http://developer.apple.com/library/ios/#releasenotes/General/RN-iOSSDK-6_0/index.html
The problem is the height setting. You somehow have to try to delete it. If you have added other constraints that are "sufficient", it should become deletable.
At the moment you have one user constraint for the height that is "Greater or equal" and an "Equals" constraint as well. Clearly, those are not working well together.
Maybe there is a conceptual error as well. The lower image view should not be fixed in position, so the distance to the lower image view will not be a "sufficient" constraint to let you delete the fixed height.
I think it should work if
the lower image view has a fixed height and
a fixed distance to the text view above, and
the text view has a minimum height as well as
a fixed distance to the image view above
(which should be fixed in relation to the superview).

Set UIView height based on inner view height using constraints

I have one UIView and inside that, N UILabels which are laid out relative to each other.
The containing UIView has a background color, I want to extend the UIView to be high enough to cover all labels inside it, so the background color is behind them all.
(I'm embedding them in a UIView so I can have the labels inset from the view edges.)
Is there away to make the UIView's height expand to fill its content? I can't figure it from the constraint options, it seems like its all relative to superviews.
Normally I'd just work out the frame sizes programatically in viewDidAppear but those are getting reset by the constraints system, AFAIK.
I think I actually worked it out though.
I had the labels height set manually from when I drag-dropped and resized it. Deleting the height constraint on the UILabel made it size to fit content, which causes its superview to resize too. At least I think that's the case, I'm new to constraints.
Will leave the question up since it will probably bite someone else too.

Resources