I have an UIViewController that contains the main UIView and inside of this are a small UIView on the top and a UITableView that fills the rest of the space.
All the design has been done with Storyboards and autolayout, so basically there are these constraints for the upper UIView:
Top space = 0px to superview
Leading space = 0px to superview
Trailing space = 0 px superview
Height = 44px
And these for the UITableView:
Top space = 0px to UIView
Bottom space = 0px to superview
Leading space = 0px to superview
Trailing space = 0 px superview
Everything works fine and resizes properly when using a different screen size or orientation. What I am trying to do now is deleting the top UIView programmatically and then I want the UITableView to fill the space to the top of the superview.
I know I could create programmatically a new constraint for the UITableView, but what I am looking for is for a low-priority-constraint? already defined in the Storyboard that can coexist with the ones already defined before.
Any other trick or workaround would be also appreciated, the only restriction is that everything should be designed in the Storyboard and everything should work after calling:
[view removeFromSuperview];
Here is the design:
just update the tableview's frame to fill the entire window after you removed the top view from it's superview
You only need to add another top constraint, one to the top layout guide, and then edit it to have a priority of 900, and a constant value of 0. If you already have the top view in place, you'll have to drag from your lower view to the main view in the list on the left since you won't be able to access the main view in the canvas.
Its very easy, as you have already made Height constraint for top UIView and vertical space constraint between top view and table view.
Create instance of Height constraint in respective implementation (.m) class.
#property (strong, nonatomic) IBOutlet NSLayoutConstraint *topViewHeightConstraint
then when you don't want top view, write topViewHeightConstraint.constant = 0.f
As you have already made vertical space constraint between top view and table view, table view will take whole space of super view.
When you want top view again just set constraints value.
Related
I'm having this weird issue with my constraints which causes the UILabel (Caption Label) to be a fixed height instead of dynamically changing height depending on the text.
I have a view (Vertical View) with a top constraint on the label above it. The Vertical View contains a view (called View) which I'm using as a divider that is centered from top to bottom with a width of 1. On the left of the divider is a UIImageView (Left Image View) with constraints leading, top, bottom equal to superview and trailing equal to View. I want to do the exact same thing to the UIImageView on the right of the divider but here is where my issue comes up.
If I use a fixed height as seen below, the UILabel above Vertical View dynamically changes its height like I want but this is obviously not how I want the UIImageView on the right to appear. I want it to be similar to the UIImageView on the left of the divider with equal height and width.
If I set the top constraint of the UIImageView on the right to the superview Vertical View, similar to the UIImageView on the left of the divider, the UILabel above Vertical View doesn't dynamically change height anymore. The UILabel now has a fixed height which I believe comes from the fact that UILabel has a height of >= 14.
How can I properly set the constraints so that I can have both UIImageViews next to each other with equal and height contained within the Vertical View and still have the UILabel above Vertical View dynamically change height depending on the text that I set the UILabel to?
On the RightImageView, you first need to get rid of the "Height = 50" constraint. This is what is causing it to be small.
Next, if that alone doesn't fix you, can you try setting the following constraints instead of using the superview for the constrains (instead make it mirror the LeftImageView):
Left: Leading spacing to divider view
Top: Align top edges to LeftImageView
Right: Horizontal space to superview (your vertical container view)
Bottom: Align bottom edges to LeftImageView
This should allow the views to remain the same height and width (assuming your distances between left/right edge of vertical container view are the same, and the distances between divider are the same).
Now, ensure the size constraint for width of the divider is set to 1 and not >= 1. Also, ensure the vertical container view has a Compression lower than the Label.
One final note--your screenshot shows the result that IB is showing you (with the dotted yellow box) on the LeftImageView. One you update your constraints correctly, this yellow box should go away.
Regarding the UILabel - if you want this to grow dynamically, you need to do the following:
myUILabel.numberOfLines = 0;
myUILabel.text = #"Enter large amount of text here";
[myUILabel sizeToFit];
In my UITableViewCell, I have two UIViews stacked on top of each other. Let's call them Top and Bottom.
The Top view has leading, trailing, and top constraints to superview. It has a height constraint of 20.
The Bottom view has leading, trailing, and bottom constraints to superview. It has a height constraint of 20.
Top and Bottom have a vertical constraint.
What is the easiest way to programatically "hide" the Bottom View (and have the Top View touch the bottom of the superview)? I prefer not to create any more constraints, since I did design this in storyboard, and I prefer not to activate/disable constraints.
If you don’t need to target iOS 8 and below, the easiest way is to embed the two views in a UIStackView. You can then simply hide a view by setting its hidden property and the stack view will automatically update the layout:
The stack view automatically updates its layout whenever views are added, removed or inserted into the arrangedSubviews array, or whenever one of the arranged subviews’s hidden property changes.
Since your parent view is a table view cell, you may have to tell the table view to recalculate the cell heights (unless you’re using autosizing cells, then this may work automatically, I’m not sure). You can force a recalculation by sending the table view an empty beginUpdates/endUpdates pair:
tableView.beginUpdates()
tableView.endUpdates()
The right way:
The Top view has leading, trailing, and top constraints to superview. It has a height constraint of 20.
The Bottom view has leading, trailing, bottom constraints to superview and top constraint to Top view.
Than just make a property for height Constratint inside your cell:
#property (nonatomic, weak) IBOutlet NSLayoutConstraint *heightConstraint;
Than when you need to change the size, call this code:
self.heightConstraint.constant = 40;
[self.view layoutIfNeeded];
or with animation:
self.heightConstraint.constant = 40;
[UIView animateWithDuration:0.3 animations:^{
[self.contentView layoutIfNeeded];
}];
You can increase the height constraint of the top view to 40 and reduce the height constraint of the bottom view to 0. Personally I prefer to have the bottom view height constraint to 20 and add a constraint to the topView bottom equal to bottomView top. And if i want to hide the bottomView I just change the height constraint of the bottomView to 0.
Hope it helps. If you need I can post some pictures in Xcode.
I'm trying to make layout inside scrollview using this one tutorial link
And get the following result link
It will be appreciated for any advices or tutorial links. It needs only vertical scrolling
I am sure there must be other ways to do this but a quick fix is :
1.) Create a width constraint on ContentView in Storyborad.
2.) IBOutlet that widthContraint and set its value to the view frame width in viewDidLoad.
Suppose the name of the constraint outlet is contentViewWidthContraint.
contentViewWidthContraint.constant = self.view.bounds.size.width;
Another alternative to do so from Storyboard, is to fix the Contentview width to the view's width from the storyboard or to the Scrollview, if Scrollview already has a Equal width contraint with superview . Add the "Equal Width" contraint from Contentview to either self.view or to Scrollview (if scrollview, already has the width contraint)
Have you set up the "ContentView" width to match with the scroll view width? I had the same problem and I fixed with "Equal Widths".
"Equal Widths" will tell to your "ContentView" to use the same width of the "Scroll View", which should be fitting the screen if you have set up the constrain properly.
You can do this easily on the storyboard.
Drag and drop, with right click (important!!!), from "ContentView" to "ScrollView"
Release the click, you will be prompted with a menu, select "Equal Widths".
This should fix your problem using the scrollview with AutoLayout from Storyboard editor.
You can find a full tutorial how to use ScrollView with Autolayout and Storyboard here.
I hope this is useful for you :)
In the Storyboard set the width of the elements contained in your UIScrollView equal to the width of this UIScrollView (by selecting all elements and the UIScrollView holding in the panel on the left of your Storyboard and then setting the 'Equal Widths' constraint under 'Pin' on the bottom of your Storyboard). Just pinning the right sides of the elements to that of the UIScrollView won't work as it will adjust the size of its "display view" to the width of the largest element and if this is smaller than the width of the UIScrollView all elements will just appear aligned to its left side.
There is also another possibility that offers a very good result.
You can mark a checkbox:
O programmatically:
scrollView.alwaysBounceVertical = true
Try to set it's width to 0 & height equal to content size like this:
self.scrollView.contentSize = CGSizeMake(0, self.scrollView.contentSize.height);
This will work as you want. Try it & tell if still facing any issue.
For disabling the horizontal scroll, you can set the content size in the -(void)scrollViewDidScroll method.
[self.scrollView setContentOffset: CGPointMake(0, self.scrollView.contentOffset.y)];
self.scrollView.directionalLockEnabled = YES;
This is because scroll view have no idea where your content should end.
But when at least one item inside your scroll view has its "trailing space" constraint attached to a view outside the scroll view (usually a view the scroll view is sitting in or some other view of a higher level, which "knows" its width) - the scroll view will automatically get an idea about your wanted width and won't scroll horizontally (unless that trailing constraint implies having your content outside the screen).
Better if all items inside scroll view have their "trailing space" constraints connected either to each other or to a view outside the scroll view. But not the scroll view itself.
No additional code or extra constraints needed for this to work.
Too set UIScrollView constraints as like below code so it will occupied whole screen.Not exceed the screen size.
Leading Space = 0 from mainView
Top Space = 0 from mainView
Bottom Space = 0 from mainView
Trailing Space = 0 from mainView
You need to set the width of UIScrollView equal to or less than the width of your Parent View. Two ways to do it:
1) You can do this in Storyboard via layout constraints
2) You can do this programatically:
self.scrollView.contentSize = CGSizeMake(self.view.frame.size.width, self.scrollView.contentSize.height);
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 would like to add a subview inside a storyboard as follows: it should contain a UILabel and a UISwitch and should be just large enough such that the two controls fit inside with a constant horizontal distance in between them.
To this end I do the following in Xcode 5.1.1's Interface Builder:
add the view
add the UILabel as its subview; add leading constraint to superview: 0; add constraint to center it vertically inside superview
add the UISwitch as its subview; add trailing constraint to superview: 0; add horizontal distance constraint to UILabel: 40; add constraint to center it vertically inside superview
When I now ask IB to update all frames, the view receives layout height zero. How can I add constraints in IB (not programmatically) that ensure that the view is as large as the "union" of its two subviews?