I have a view hierarchy on iOS arranged like this:
UIViewController
- UIView
- UIButton
- UIButton
- UIScrollView
- UIStackView
- UILabel
- UIDatePicker
- UILabel
- UIDatePicker
The scroll view is pinned to 20 from leading and trailing space on the superview, 0 from the bottom of one of the buttons, and 0 to the bottom layout guide.
The stack view has 0 leading, trailing, top, and bottom space to the superview (the scroll view).
I like how this looks in vertical orientation:
But in horizontal orientation, I think the long lines extending beyond the main content of the UIDatePicker are kinda ugly:
I've tried many permutations of constraints (max width + center X on the UIDatePickers, increasing various content hugging priorities, no width constraints on the UIScrollView and center X on it), but all have resulted in ambiguous layouts or conflicting constraints. How can I do what I'm aiming for here?
EDIT: With the constraints as suggested below (ScrollView pinned to container, StackView pinned with 0 Trailing, Leading, Bottom, and Top space to the ScrollView, and a width equal constraint on the date pickers) the StackView refuses to expand its width and stays pinned to the left of its parent.
This happens even though there are leading and trailing constraints set to 0 on the StackView.
Change the Alignment of UIStackView to Center.
Add a width constraint to DatePicker = 315
Now the stackview will keep the DatePicker to Center with width 315 in both potraite and landscape
Related
This is my setup:
I do not know what I am doing wrong. The image view is bigger than the size of the view and of the scroll view. The constrains are set al followed:
Scroll view: equal heights to View * 0,5, equal width to View, center Y and X to View.
View (inside Scroll view): pinned all zero's inside Scroll view, equal heights and width. I also tried instead of equal heights and widths to center X and Y inside Scroll view, but it won't scroll.
How can I let the Scroll view scroll? Thank you.
Add a leading, trailing and top constraint and equal height of UIScrollView to superview with 0.5 multiplier. Now to your contentView (the UIScrollView subview), add a leading, trailing , top and bottom constraint. Also add equal height and width to UIScrollView. Set the height to a priority of 250. Add constraints for UIImageView inside this contentView.
Since the contentView will have a fixed height of low priority equal to the UIScrollView height. This fixed height constraint will break once the UIImageView total height(based on the constraints you add) will get larger than the UIScrollView height and the content will become scrollable. So at the very least you will always have a view half the screen size and become scrollable once the content becomes too large vertically.
You need to give contentSize to scrollview.
ScrollView.contentSize = CGSize(width: 1000, height: 500)
Which constrains have you given to imageview?
set constraint of imageview:
Trailing ,leading,top,bottom - 0 and also give height constraint.
I have a Controller with 4UILabels that are constant height throught all the iPhones, below the lastUILabel there is aUIView with a page controller(with aTableView inside that page controller).
What I want is that theUIView take all the height that he cant :
example: Screen of 600 height
4UILABELS = 200 height
TableView = it should get 400 height
Screen of 800 height
4UILABELS = 200 height
TableView = it should get 600 height
I need 1 constraint more to set the height of the view,What I have defined is :
EqualWidth constraints to superView
LeadingSpace to SuperView
Top Space to super VIew
The following constraints should align everything for you so that the UILabels stack vertically, each have height 50, and stretch to the edges. The UIView will take up the remaining space regardless of the screen size.
All UILabels
Pin leading edge to superview
Pin trailing edge to superview
Add height constraint set to 50.0
UILabel 1:
Pin top edge to superview top
UILabel 2:
Pin top edge to UILabel 1 bottom
UILabel 3:
Pin top edge to UILabel 2 bottom
UILabel 4:
Pin top edge to UILabel 3 bottom
UIView
Pin leading edge to superview
Pin trailing edge to superview
Pin top edge to UILabel 4 bottom
Pin bottom edge to superview
UITableView
Pin leading, trailing, top and bottom to its container view so it fills the area.
I assume that you are creating this UIViewController in a Storyboard.
You should be able to put all the labels in a container view which you give the constant height of 200 points, as you specified. Make a vertical constraint from "Top layout Guide" to said container view, maybe with the value 0. Drag an UITableView and place it below the container view. Dont give it any constraint regarding height. Make a vertical spacing between the (bottom of) container view and the (top of the) UITableView with value 0 and a vertical spacing between the (bottom of the) UITableView and the Bottom Layout Guide with value 0.
So it will be (V:0 means vertical spacing, constant 0):
Top Layout Guide
V:0
Container View - Height: 200
V:0
TableView (dynamic height)
V:0
Bottom Layout Guide
This should work.
(And then of course you need to create constraints regarding width and also internal constraints for each UILabel inside the container view. Let me know if you need help with that.)
I'm trying to make a translucent black rectangle with some text in it, to convey some info to users. It seems to work, but when the phone's text size is large then the label's contents are cut off -- the view won't expand its dimensions.
To create this I added a UIView with a black background and rounded corners, made it somewhat transparent, and placed a UILabel inside it. Constraints on the view should allow it to grow wider when the phone is rotated, and constraints on the label keep its edges pinned to the view.
Here are the view's constraints:
Align Center X to: Superview
Align Center Y to: Superview
Trailing Space to: Superview >= 40
Leading Space to: Superview >= 40
Width >= 200
Width <= 300
Height >= 100
Height <= 150
And the label's constraints:
Trailing Space to: Superview Equals:Default
Leading Space to: Superview Equals:Default
Bottom Space to: Superview Equals:Default
Top Space to: Superview Equals:Default
When run on an iPhone 5, the view's size is 200 x 102 for some reason and the text is truncated, even though its constraints allow it to go up to 300 x 150. What am I doing wrong?
Just set UILabel Top/Bottom/Lidding/Trailing constraints to zero because it has intrinsic content size. It means label will wish to become that wide to contain its string value all visible. Look at this article
Create constraint programmatically
_constraint=[NSLayoutConstraint constraintWith...];
[self.view addConstraint:_constraint];
//...
_constraint.constant=40;
Use outlet if all the constraints are defined in IB. Just connect it to your constraint.
#property (nonatomic,weak) IBOutlet NSLayoutConstraint *constraint;
I have a problem with Auto Layout. In my UIViewController I have the following view hierarchy:
- View
-- Small Bar
-— Scroll View (leading, trailing, bottom to superview, top to Small Bar)
—-— Container View (leading, trailing, bottom and top spaces to superview)
———- UILabel
———- UITextField
———- UILabel
———- UITextField
———- UIButton (full width, top to UITextField, bottom to superview)
I want the UIButton to be always hooked to the bottom of the view, depending on the size of the screen. If, however, after rotating the screen, it will turn out that the button will cover other views, it will have constant about 30 from the last object in the hierarchy.
I've tried with relations between UITextField and UIButton with "Greater Than or Equal" - 20 constant, but it didn't work. I've tried messing with priority, but effect was the same.
Here are the screenshot :
Any ideas?
For making the bottom control to be stayed there always then scroll view should be inside a container view.
Look at this view hierarchy:
-View
---BarView(Leading, trailing and top space to super view, Height)
--=ContainerView(leading, trailing, bottom space to superview, vertical space to BarView)
-----ScrollView(leading, trailing, top, bottom space to super view)
-------UILabel
-------UITextField
-------UILabel
-------UITextField
-------UIButton(leading, trailing to superview(ScrollView), Height, Bottom and Right to ContainerView)
It is working fine as you expected.
Refer this screene
Try it out.
I am programming an iPad application that uses auto layout to correctly position views on the screen in both portrait and landscape orientation. The layout (simplified) looks like this:
-UIView
-UIScrollView (all spacing pinned to superview)
-UIView (top, bottom spacing pinned to superview, leading and trailing spacing pinned to root view to prevent horizontal scrolling)
-UIImageView (leading and trailing spacing pinned to superview, height pinned to fixed value)
-UILabel (leading, trailing, and top spacing pinned to superview)
I have got the ScrollView to work, but I want the UILabel to scale vertically to fit its multiline content, which is not working. It does adjust its height based on the content, but it uses the (fixed) frame width specified in the storyboard to do so, instead of the actual width that is calculated by using the constraints, which changes when the device changes orientation. This leads to the UILabel being too high in landscape mode. Since a UILabel's content is vertically centered, this makes the top margin of the text too large.
I have no idea what is causing the trouble. Trying to add a height constraint to the UILabel and then calculating the height programatically using [NSString sizeWithFont:constrainedToSize], but this resulted in the exact same problem (I was unable to get the correct width as input). How do I fix this?
Although the reason for the problems is still unclear to me, I fixed the problem by subclassing UILabel and putting the following code:
#implementation MyLabel
- (void)layoutSubviews
{
self.preferredMaxLayoutWidth = CGRectGetWidth(self.bounds);
[super layoutSubviews];
}
#end