Position and size are ambiguous for "Image view" - iphone

I am trying to set a UIImageView has no fixed size and width in the storyboard. I set the leading space to container to greater than or equal to 20, top space to the container to greater than or equal to 20 and trailing space to container to greater than or equal to 20 and vertical spacing to a UICollectionView, the UICollectionView satisfy the constraints. But the UIImageView don't work, it's telling me it's Position and size are ambiguous. How can I make it work? My Idea is no matter how large the image view, it will always keep 20 space to leading, top, trailing and bottom.
I have set the height and width to be greater than or equal to some value and their priority to 999, it's lower than the leading, top and trailing priority. and I have set the imageview to center horizontally. but i get height and vertical position are ambiguous for “Image view”.

Can you see what happens when you add height and width constraints to the UIImageView, but set their priorities to some low value, e.g. 1? It should help, but now UIImageView won't be centered. You can fix it by enclosing UIImageView in another view (empty UIView) and centering it in it both horizontally and vertically.

When you get this error:
Position and size are ambiguous for “view”
Probably following constraints are missing/incorrectly set:
Width constraint (size issue)
Height constraint (size issue)
Alignment constraints (position issue)

If you are using Stack Views, make sure the Photo Image View is inside the Stack View! (As in the Apple Tutorial)

If you want to give margin kind of thing into button through coding than please try these if it'll work
[button_Name setTitleEdgeInsets:UIEdgeInsetsMake(0.0, 12.0, 0.0, 0.0)];
I hope this will work..!!!

In cases where the height/width are not ambiguous at runtime, but ambiguous at storyboard time, e.g., setting an image dynamically, having a container view, etc, I try to add constraints with the placeholder checkmark checked to silence xcode.

Related

Swift - why elements don't have equal sizes?

I have a Vertical Stack View on my screen (Alignment = Fill, Distribution = Fill).
In it there are from top to bottom:
Label (no constraints)
Vertical Stack View (height=21)
Horizontal Slider (height=21)
Label (no constraints)
I was expecting that both my labels (elements 1 &4) will be of equal size and will occupy the majority of the screen and 2nd & 4th elements therefore would be in the center of the screen. But in reality my bottom Label's height is sufficient only to fill it's text while my top Label takes the majority of the space.
I tried to change the Distribution of my Stack View to Fill Proportionally, but in that case my top label becomes smaller than the bottom one.
Why is it happening? How can I make my Labels to become of equal height?
PS I noticed a warning about Content Priority Ambiguity but I can't figure out what should I do about it
To make both labels equal in height I had to select both of them and add a constraint Equal Heights.
Warning about Content Priority Ambiguity was not about them, it was about horizontal labels. To remove warning while keeping their placement I changed Distribution of the horizontal Stack View to Equal Centering.

Changing Stack View dimensions to be a ratio

I am wondering how I can change the dimensions of a stack view to be a ratio, specifically 7:6. So far, I have constrained the Stack View with "Align Center X to: Superview" and "Height Equals: 400" and "Align Top to: Safe Area Equals: 100." How can I maintain a constant ratio between the width and the height across all devices? Thanks!
For User Interface, I am using Storyboard, not SwiftUI.
What I have right Now
I am not exactly sure why this doesn't work, but it is probably my understanding of aspect ratio. My main issue is how to use the (phone width - 20 points) to determine the height so that it is a ratio.
Expected result, but I don't want to manually set the height and width, rather a ratio
I don't want to manually set the height and width
Then you should remove the "Height Equals: 400" constraint that you currently have! After that the layout should be fixed. It should look like:
Just for completeness' sake, all the stack views should have distribution=fill equally, and alignment=fill.
The height=400 constraint is causing the constraints to conflict. If height = 400, then width would be about 467 to get an aspect ratio of 7:6, but the width of the super view isn't enough for that. But you also require the leading and trailing of the stack view to be pinned on the leading and trailing of its super view! These constraints can't be simultaneously satisfied.
Note that this layout doesn't look quite nice when in landscape, since the width would be very large and the available height is small. You might want to add variations to install/uninstall constraints based on size classes. In landscape mode, you could pin top and bottom rather than leading and trailing, for example.

Horizontal Stackview in swift: how to wrap according content

I use a stackview (horizontal) with this setup:
Inside it, I have just 3 buttons (without text, only icon). The height/width button are set by constraints:
And the result is:
BUT I don't understand why my second button has a huge width... even if it width is fixed at 44.
Have you got some explanations guys please?
Thank you very much!
Your settings are just conflicting, that's the answer. It must fill stackview width with 3 buttons 44pt each + 6pt spacing between them, and this can't be resolved, because stackview width is bigger than 44*3 + 6*(3-1).
If you want all buttons be on the left with 6 point spacing, then remove trailing constraint for stackview;
if you want buttons to fill the full width -- then remove spacing = 6 and set distribution = equal spacing
Try to put the distribution to equal spacing on the stack view. That means that the spacing will be equal between every button. If you do not have any constrains on the stack view that affects the width then that should work.
Otherwise you need to increment the spacing value in order for the buttons to have equal widths.
Thanks for the question!

Stack view constraints changes top-layer's view width

I have a stack view holding 2 images.
One image's width to be lower or equal to 140 and 1:1 ratio
Stack view top constraint 20 and trailing constraint 5
When I want to set the stack view leading constraint to 5 (looking at the safe area leading) it enlarges the safe area to a width of 1920 and I have no idea why it does that.
It might have something to do with that the total width of the stack view (including the constraints) is smaller than the width of the safe area so it's ignoring the images width constraint and enlarging it to the default size (1920)? Because, when I change the stack view's distribution to fill proportionally instead of fill equally it does obey to the image's width constraint and the safe view's width stays normal.
If I am thinking correctly, how can I find a workaround for this?
Thanks in advance.
EDIT: I was trying to think logically and I found a solution by changing the image's width to GREATER or equal to instead of SMALLER or equal to. I was following a devslopes guide and in that Xcode version (Beta XCode9) it did work, it just gave a warning it wasn't obeying that constraint anymore (I think it was saying that, I just saw the width being red). So it works now, if anyone has this problem following their guide, just do what I said and it will work.

Expanding UITextView inside a Stack View with scrolling enabled

I am trying to achieve something with Auto Layout and Stackview. I have a Vertical Stackview with a UIView, UITextView, and UIView in it as shown below.
I have checked out the previous answers here but couldn't find a clean solution to achieve this.
The UITextView is editable and must expand as the user types in it - for this I have disabled the scroll for the UITextView in the IB. I also have a height constraint set on the UITextView set to "Greater than or equal to" 10 and number of lines set to 0, so that the UITextView takes the intrinsic height at run time while the user types. I also want the expansion of the UITextView to continue until the UIStackView bottom edge reaches the Keypad accessory's top edge. I have been somewhat able to achieve the expanding UITextView part with my stack view pinned to the top, trailing, and leading edges of the Superview but I keep getting an error that the stackview needs Y position or height which is understandable but if I give it a fixed height or bottom constraint then the UITextView simply won't expand.
I also am not sure how to stop the expansion of the UITextView when it reaches the top edge of the Keyboard accessory view.
The code that I have so far is
let allowedHeight = self.view.frame.height - (self.keyboardHeight! + self.accessory.frame.height)
Basically find the allowed height in the view frame by subtracting the keyboardheight+Accessory view height. This calculation happens correctly. Next I do this (inside textViewDidChange) in hopes that just enabling/disabling the scroll on the UITextView would work but it clearly doens't since the whole text view then weirdly jumps up and down with every key stroke.
func textViewDidChange(_ textView: UITextView) {
if stackView.frame.height >= allowedHeight{
textView.isScrollEnabled = true
}
if stackView.frame.height < allowedHeight{
textView.isScrollEnabled = false
}
}
What is the best way to achieve what I am looking to do?
Couple notes...
I think you'll be better off setting the Max Height of your UITextView rather than of your UIStackView. The Text View will expand / contract based on its content, so you can set a <= height constraint.
Calculate the "elementsHeight" - the vertical size used by your top and bottom views, plus any spacing - and set the "max text view height" to the view height minus elementsHeight ... and subtract keyboard height when visible.
Update the text view's height constraint constant when "max text view height" changes.
Then set up an Observer for the text view's .contentSize ... and enable / disable scrolling based on .contentSize.height compared to "max text view height".
Needs a bit of hoop-jumping, to make sure you update sizes when subviews are laid-out, and to make sure you don't get in a recursion loop.
This is how I set it up:
The initial height constraint on the text view is <= 40 - but that doesn't really matter, as it will be changed via code every time the views layout differently.
I put up an example on GitHub -- it works, but is really just a starting-point. Take a look if you're interested, and pick it apart. https://github.com/DonMag/ExpandingTextView