UIImageView making other Views inconsistent - ios

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.

Related

Xcode: constraining varying height UILabels to fixed size container

I’m building an iOS app which includes a quiz. Questions are displayed in the upper portion of the screen (see below). There are always five possible answers. The thing is: the answers are procedurally generated and vary in length, which leads to line breaks in the label sometimes.
This is the current state
Maybe it’s hard to tell from the picture, but the spacing between the first and second and then between the second and third is not the same as I intend it to be.
This is what I had in mind
Essentially, I’d like the top- and bottommost labels to have the same space towards the container. The labels in the middle should all have the same spacing between each other, but should also adapt, if one of the labels gets bigger (when the size of a text is longer than the width and a line break occurs).
To achieve this, I tried the following:
Organise the labels as a stack view:
Nearly worked, the only problem I have here is, that the size of the
labels is calculated after the stack view is displayed, which leads to wrong constraints/paddings/margins being applied to the (possibly) longer texts at runtime.
Organise the labels with regular constraints
I tried setting the
priority of the constraints for the middle labels lower than
that of the top- and bottommost ones, so those would be the ones
to resize, if the labels enlarges, but it appears that at
runtime one of those is chosen to shrink, whereas the others
remain at their default size.
I'd really appreciate if you could help me out, constraints always seem to be a pain in my neck...
Agreed... I think UIStackView works fine, just have to set it up properly.
Also you may need to call .sizeToFit on the labels when you set the text.
I put up an example for you - the sizing is not exact, but you should be able to follow the technique...
https://github.com/DonMag/StackViewFun
I think the best practice in your case would indeed be to use a UIStackView. Then you have multiple option in solving this problem:
You can set the distribution of the UIStackView to Fill Proportionally and set a Minimum Font Size or Minimum Font Scale to your UILabels.
You can also set the distribution of the UIStackView to Fill and then manually specify the height of your containers. The UILabels should still have some Minimum Font Size or Minimum Font Scale.
EDIT:
I just realized you want to keep all UILabels to have the same font sizes. Then a possible solution would be to embed the UIStackView into a UIScrollView and constraint the UIStackView's Leading, Trailing, Top and Bottom constraints to the ones of the ContentView of the UIScrollView. In this way the height of the UIScrollView will adapt in accordance of the needed height by the UIStackView.
Hope this will help you!

How do I make two equally sized imageviews cover the whole screen

I implemented a viewcontroller similar to the one in this question:
iOS two views cover exactly half of parent view
I get the desired result. The problem is that when I add a UIImageView into those two containers, the result get resized and ruins the symmetry. How do I prevent Imageviews from changing the size of their containers? I need to use AspectFill for these images.
I don't think the containers' sizes are changed. You just need to set their clipsToBounds property to true to avoid overflow.
If you use Reveal you should see the containers' sizes are not changed even if pictures inside them are bigger than themselves.
I'm unsure I understand what you mean about adding UIImageView into those controllers causing the views to resize, so forgive me if I'm getting this all wrong...
It sounds as though you've created two views of equal height that, together, consume the entire vertical space of the screen. After having done that, you want to add one or more UIImageView's to each of the original two views. Unfortunately, when you add the UIImageView, the enclosing view is resized.
Assuming I have that correct...
Are you doing this with Interface Builder either in an XIB or Storyboard file? If so, you ought to be able to achieve this with the proper set of constraints.
In the following image, I've laid out what I describe above.
As you can see, I have a red view on the top half of the window and a green view on the bottom half. The red view contains a UIImageView that is 75% of the width and height of red view, with its origin at (20, 20) within the red view.
The scene is configured as shown below:
The constraints on "Upper View" are:
You can see from this that Upper View is flush with the left, right, and top of its superview, and that its space to Bottom View is 0. You'll have to trust me that Bottom View is set up the same way.
The height of the Upper and Lower views is "Proportional" as shown in this constraint:
To achieve this "Proportional" setting, you first make the height of Upper View equal to the height of the superview, and then edit the constraint, changing "Multiplier" from "1" to "0.5."
The height (and width) of the Image View is proportional to that of the Upper view, as shown here:
If you set it up this way, you ought to be able to accomplish what (I think) you are looking to accomplish.
If my original assumption of what you are trying to achieve is incorrect, please post images of what you've got and how it's not working.

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

Hide a view and adjacent gap with autolayout

I have the following configuration of a view:
Sometimes I have an image to put in the image view, sometimes I do not. If there is no image to show, I would like the Title label to be extended to the right, occupying the whole space of the image and the gap between the label and the image. I assigned a constraint "less than or equal" to the width of the image view, so I guess it might get zero width if the image property of the image view is null. But how do I remove the gap between the image view and the title label? I know it is possible from code by defining an outlet for the gap constraint, but is it possible in a simpler way, maybe from interface builder?
Nope, this isn’t possible in XIB. I’ve filed enhancement requests (starting even before this shipped). File more! The more votes this gets, the more likely it is to happen.
We ended up adding an outlet onto our subclass of ImageView that we point at the constraint we want to go away, and in the subclass disabling the constraint when the image is nil (we use different tricks to disable it in different places, since there’s no one single easy way).

How to prevent UIImageView from resizing with Autolayout

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/

Resources