Hi I'm trying to understand auto layout and have a simple question. Correct me if I am wrong, but unlike labels and buttons, image views/views do not have an intrinsic content size which makes working with them in auto layout a tad bit harder. I just want to know what constraints I would need in the examples below so they would show up appropriately in both portrait and landscape, if I were to be working in the W:Any H:Any size class.
In the case of the image view I was also wondering if the outcome would change if I were to apply the constraints and then the image.
https://s15.postimg.org/s5814ct3f/Screen_Shot_2016_09_03_at_6_20_22_PM.png
https://s9.postimg.org/jxdeud13j/Screen_Shot_2016_09_03_at_6_20_56_PM.png
Thanks!
You can apply this:
1) Select an imageView, and choose following 4 constraints:
top leading contraint
width constraint
aspect ratio constraint (so it is going to be dependent on its width and it won't be distorted)
horizontal center in container constraint
If you are likely to need to change the image size after you've implemented the autolayout, you may need to change constraints. Thye are responsible for handling items and their sizes, rather than then dimensions (width, height) that are in size inspector.
I made a little animation to see, how to change constraint in interface builder, while you are designing your scene:
Related
It gives me the following warning: Need constraints for: Y Position or height. I can get it working with for example TextView, by disabling "Enable Scrolling" but ImageView does not have a setting for something like that. I've also tried selecting my view controller and enabling/disabling "Adjust Scroll View Insets" which gives no results.
EDIT Image of my hierarchy.
The layout is ambiguous, because AutoLayout does not know the height of your UIImageView instance. Constraining views against a UIScrollView is somewhat special, because the ScrollView's contentView needs to calculate it's size based on the subviews. To to this AutoLayout needs to be able to calculate the dimensions of all the subviews without relying on the ScrollView's size.
There are different ways to solve this.
Add a explicit height constraint to the imageView
Add a aspect ratio constraint to the imageView
Set a placeholder intrinsic content size in the Interface Builder
I'm having issues programmatically changing constant for a height constraint. Debugging my layout I've figured out that somehow there's a height constraint automatically being created, I'm guessing this constraint is causing the issue.
How can I get rid of those (content size) constraints?
Those content size constraints in the view debugger are there to represent the intrinsic content size of the view, and are perhaps a little misleading. The intrinsic content size can act as a required constraint, but only does so if you set the content hugging and compression resistance of your view to have a required priority. Clicking on those constraints in the view debugger seems to always show them with a required priority (i.e., 1000) even when that is not necessarily the case.
Having said that, you can adjust the relative priority of these content size constraints in Interface Builder using the Size Inspector.
You can also adjust them programmatically with the setContentCompressionResistancePriority(_:forAxis:) and setContentHuggingPriority(_:forAxis:) methods of your UIView instance.
You can read more in the Views with Intrinsic Content Size chapter of the Auto Layout Guide.
I am attempting to get the auto-layout to work correctly. For some reason, when I change the size of the device, all of the images and buttons are out of place and don't resize at all. This is true for the 3.5 inch screen, as well as the ipad retina. When I run the simulator, the app shows exactly how it shows in storyboard. Auto-layout should be resizing everything so that this does not happen. please help!
The issue is that constraints don't scale. When you set a constraint height to 200 it will always be 200, even if the screen is only 100 high. So what you need to do is try to set constraints that makes the size dynamically rather then set the constraint height/widths yourself.
For instance, on your first label under the UIImageView set the constraints leading and trailing to 20, then set the label constraint to center horizontally on the UIImageView. No other constraints for the label. This will cause the label to shrink in width since its set to be 20 away from each side. The height will not change since there is nothing "pushing" it to shrink since you are missing a few constraints, but basically you need to use the top, bottom, leading, and trailing, constraints to the UIViewController view in order to "scale" the elements.
If you'd like I could try and set the constraints for you if you upload the project and you can then watch how I did.
Edit
It's hard for me to know what kind of behaviour you'd want, but something has to scale or change size in your set up. The easiest would be to resize the UIImageView. It's basically impossible to make it look exactly alike in every screen size, though, so you'll have to play around a bit with constraints until you understand how they work and how to adjust them according to what you want. One way is to create the layout you want and then connect them to code and scale them depending on size of the screen (this is a bit of a pain, I did that in a project recently and it took a bit of time and effort).
The easiest approach is to make the UIImageView to change its size when it needs to, and add extra space in the bottom. Here is a demo project I threw together earlier. Download here
Profile pic
1) first you set the profile pic image center horizontal to the content view
2) set height and width for the profile pic
3)set top space constraints to content view
Change Profile pic label
1)set central horizontal to profile pic
2)set width and height
3)set vertical space between profile pic
Challenges Accepted label
1) set vertical space to profile pic label
2) set Leading space to container
3) set height
and do same for the below two content . i didnt tested. check it and try
After a long night of struggling, I figured out what I needed to do. I was setting the individual view controllers to have a simulated size of 4.7inch. This made it hard for the constraints to scale across all devices since I was setting the constraints for a specific screen size. However, this would be the way to go if using size classes.
I solved my issue by using the standard 600 X 600 canvas that is available before choosing a specific size. This way, I was able to set constraints that scaled down for the smaller screens, and scaled up for the larger/HD screens. This works perfectly with auto-layout. Hope that helps someone!
I want to set the content view of a scrollview to whatever the current screen size is, but AutoLayout is doing some funky stuff. This is trivial in code... just create a scrollview with a frame that is the superview's bounds. Then create a content view with the scrollview bounds and populate it and set the alwaysBounces... properties to YES. In interface builder though, this is some kind of sinful thing it seems.
I know Autolayout handles scrollviews totally differently because it wants to infer the content size based on constraints. My approach that failed is setting the scrollview to have 0 distance to its superview (all sides attached). Then, the same with the content view (the single scrollView subview)- attached to all superview edges. Then the precompiler thing complains about not knowing the content size, so I set a width and height constraint at placeholder to be removed at build time. But the result is a (CGRect){0,0,0,0} contentView. The 0 space to trailing edge and bottom of superview are totally ignored.
So how can I make a scrollview with a dynamic content size based on the screen size?
Bonus points if you can explain how you would do the same, but for a content size of 2x screen width.
You can try setting a constraint for the content view's width to equal the scroll view's width (for your bonus question: with a multiplier of 2). Same for height.
Not sure what the point of having a scroll view whose content is always the size of the scroll view is. By definition it wouldn't scroll, right?
Xcode 5
I'm trying to learn the auto-layout system. Thought I would start with something simple, but I'm already getting stumped :-)
Scene: Main View -> ImageView -> View
I want to support rotation such that the Image rotates and centers on the screen, using Aspect-Fit content.
I want the smaller view to maintain it's relative position to the top edge of the UIimage view. It does't seem to understand the aspect-fit, and it aligns the sub view along the top of the main view, not the fitted image.
I think it has something to do with the fact that the small view is a sibling of the Image, and not a sub-view. I can only seem to create constraints to the superview.
.
You haven't started with something simple!
An aspect fitted image view doesn't actually change its size under auto layout depending on the image, it fits the image into the bounds that the constraints have determined, leaving the rest of its frame blank. If you set a border or background colour on the image view you will see this.
To achieve the effect you're after you would need to do the aspect fitting calculation yourself and modify the sizing constraints on the image view appropriately.