How do you prevent a UIImageView from resizing after adding a constraint to align horizontally to the center? Every time I run the program with the restraints in place the image that was originally sized 300x300 takes up the entire screen
As soon as an image view comes under control of auto layout, its size is determined by its image — unless you take measures to prevent that. For example, you can add width and height constraints, or you can add external top-and-bottom and leading-and-trailing constraints that set the size relative to the superview or whatever.
(By the way, the very first thing you should always do is examine your interface in the View Debugger. If you really added only a constraint to align horizontally to the center, that is an error — an insufficient constraint — and the View Debugger will let you know of that fact.)
Related
I have a horizontal stack view, with an empty UIView on the left side and a label on the right side. In storyboard builder, it looks perfect (just look at the green row):
However when I run the app on Sim or device, the color view just collapses and disappears:
I have the stack view set to center alignment and proportional distribution.
If I give the color view a set width, it works well in Sim/device, however I get a warning in the interface builder, which annoys me. I assume there's a more correct way, but I don't know what that is. With set width warning:
It only allows me to delete the width=50 (the one I entered). It won't allow me to remove width=0 (not set by me, seems to be default).
Anyone have any ideas?
First, you set a proportional distribution, which tells the stackview: "Hey stackview, lay-out the views proportional". Then, you set a fixed width, so you are saying: "Hey stackview, give this a ... width". Both can not go together, since they are different.
Either make 2 stackviews, or add an UIView in to the stackview, and make that image proportional to his parent UIView.
So:
-Stackview
-UIView
-Image proportional to UIView
-Label proportional to UIView
-UIView
-Image pro...
-label...
-UIView
-Image...
-label...
And set your StackView to "Fill equally" to use this way.
Working with StackViews
A method that works is to make the strip of color beside the label an image and use UIImageView instead. StackView will then consider the UIImageView to have content and not compress it. But that will obviously cost more resources. Also to note that the images used for the strips have to be the same size or the StackView will compress them to different sizes the screen too.
Another is to set the Distribution property of the StackView to Fill Equally this will give the strip and label each half the space. It will work but may not provide the visual you are looking for.
Alternatives
By the amount of information provided, I see no requirement to use StackViews. You may instead just apply constraints that gives the strips and fixed width.
You can also try using auto layout by setting each strip to fix there distance to the leading and top while maintaining its size(actually the default settings) and the label to the same except also fixing its distance to trailing and width to scale with superview.
I am developing a component in a separate xib file which I then add to my controller. The issue is that the trailing side of my inner containers goes out of bounds of my outer container. To be more precise my subview width fits into my view controller, but elements inside subview are going out of that container. The constraints are all set to 0 (top, bottom, trailing, leading). I have set clip subviews to true for the container. Images below demonstrate the problem. Right label on the first image goes out of container constraints when i build the app. The same will be for every element. I have played with the trailing constraint and if I set it to -40 the label appears on the screen however I feel that there has to be a better solution.
The size class that i'm using is Compact:Regular.
Actualy, you came up with the right solution. For components like labels or image views (components, that can determine their sizes implicitly based on content), it is only necessary to set one constraint in each dimension. In your situation, it should be enough to set trailing and, for example, center Y of label. The rest will be dependent on label content itself
Update
Take a look Apple's guide on autolayout and Intrinsic Content Size
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.
I created a scroll view in Xcode that works awesome because of this video.
https://www.youtube.com/watch?v=3PIm8-lKAYw
When I was messing around after I made it I found out that if I clicked on the scroll view and went to Show the Size Inspector or the fifth button on the right hand side of the screen I had the option to make a constraint called Top Space change in value that caused the scroll view to become bigger and smaller. I decided to see if I could find a way to change the constraint programmatically by simply using dot notation and the equaling it to an int value that I wanted.
So what I'm trying to figure out is there a simple way to change these constraints values programmatically that change the scroll view constraints values?
Without actually following that tutorial (and there being no code in your question) I'm going to make a few assumptions.
Yes, it is possible to change the scroll view's content size by manipulating constraints in your code. If you are creating the constraints in a xib or storyboard, you will need to make sure they are hooked up to IBOutlets so that you can access them in your code.
If you have 2 views arranged vertically that affect the vertical content size of your scroll view, increasing the space between these views would also increase the vertical size of your scrollview's content size. The following would increase the space between 2 views by 20 (assuming a multiplier of 1) and subsequently increase the scrollview's vertical space by the same amount.
// This is a vertical space constraint created in your xib or storyboard between 2 views that drive the content size of your scrollview
someVerticalSpaceConstraint.constant += 20;
Hey, I'd like to obtain what you see in the pictures: in Compact Height mode (landscape iphone) both the red and the blue view have to take all screen vertically and half the screen horizontally. In Compact Width mode (portrait iphone)they have to take all the screen horizontally and half the screen vertically. Space between views should be same size in both modes.
I used to think I have to use size classes and auto-layout constraints, but everything I tried failed miserably.
Maybe I have to use a UICollectionView and change flow direction based on orientation (if that is even possible)?
A collection view is probably overkill, because you don't want scrolling and that's the whole point of a collection view--by the time you do the sizing to stop it you'll have done all the work necessary to set a non-scrolling layout.
This is possible with Size Classes in IB. First, In general you will probably find it helpful to name the views in the Document Outline on the left in IB. You will also want to use this outline rather than try to grab the tiny constraint H-lines.
Set up all the constraints except 1) constraints linking the
OrangeView and BlueView to each other, 2) the constraints linking
the OrangeView to the top and left(leading), and 3) The constraints
linking the BlueView to the bottom and right (trailing).
Change the size class setting at the bottom to w-Compact and
h-Any in the funky box system. Now we're designing for a compact width, so views on top of each other.
Create a constraints for vertical space for BlueView.bottom to
OrangeView.Top. Also create constraint for OrangeView to
superview.leading (or ledaing,margin) and BlueView to
superview.trailing.margin. If you select any one of these constraints and look at the Size Inspector on the right (the ruler) you should see an "installed" checkbox not selected, and below that a w-Compact h-Any and another installed box, this one selected.
Now, while keeping the constraint selected just to see what happens, change the sizeClass selector at the bottom to w-Regular h-Any. Notice that in the Document Outline to the left, it should get grayed out.
Now we are designing for regular, so side-to-side. Add constraints linking the views for horizontal space, BlueView.trailing to OrangeView.leading. Also link OrangeView.top to the superview.top or top aligned to BlueView.top, and same for bottoms. You can manually edit the frame first; if not, IB will automatically fill in the wrong values, so edit these after you create them, and verify they are w-Regular and h-Any. With the ViewController selected, select "update frames" and the views should snap to their expected shape for the size class.
Let us know if this works for you or if it was unclear. Good luck!