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.
Related
I have a UITextView inside a UIScrollView. if I try to display a long text with a certain font size, the text is not showing. With shorter text or decreasing the font size the text shows up again. What am I doing wrong?
Screenshot of the autolayout here (the item selected is the textview):
The UITextView is inherited from UIScrollView
open class UITextView : UIScrollView, UITextInput, UIContentSizeCategoryAdjusting
So it is a bad practice to put ScrollView inside scrollView.
The reason why you don't see a long text in UITextView is that UITextView became scrollable. Also you didn't specify your scrollView content width so the with is calculated is as one line of your long text. But you can scroll it because you will scroll scrollView. Better way is to set label inside scrollview and set the label numberOfLines = 0. Make the label bottom padding to the bottom of your scrollView and top to some items in top of label and you will get a scrollable text.
I've just understood that you don't need a scrollView to place your long text.
You can use just a UITextView for your needs.
Remove your scrollView.
Add a UITextView.
Set constraints as described and math them with screenshot
Top Space to ReadingTimeLabel
Align Bottom to Superview / Bottom Layout Guide
Leading space to Superview
Trailing space to Superview
And you will get the result like on the screenshots
Scroller top:
Scrolled bottom:
Note: You can disable UITextView editing in attribute inspector.
But if you for some reason need a scroll view:
Set constrains as described, also match them as shown on screenshots.
Add scrollView constraints (Superview is the view where the scrollView is placed in):
-Top space to ReadingTimeLabel
-Align bottom to Superview/Bottom Layout Guide
-Align leading to Superview
-Align trailing to Superview
Please a UIView inside scrollView. Use it as container.
Add constraints for container. (Superview is scrollView)
-Align Leading to Superview
-Align Trailing to Superview
-Top Space to SuperView
-Bottom Space to SuperView
-Equal Width to SuperView
Add a UILabel inside container. (Superview is container).
Add constraints for UILabel.
-Align Leading to Superview
-Align Trailing to Superview
-Top Space to SuperView
-Bottom Space to SuperView
For the label set Lines = 0 in Attribute inspector or use the code
label.numberOfLines = 0
And you will get the result like on screenshots
Scrolled top
Scroller bottom
Try the below code:
textView.sizeToFit()
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
Using Storyboard, in UIViewController using UIScrollView, UIView as content view
Scrollview Constraints - top, bottom, left, right
UIView as contentview constraints - top, bottom, left, right, equal width height to ViewController's View.
I am using these constraints, can anyone please help me out why button is not calling?
The button is not clickable because it is below the frame of the content view. You need to remove all auto layout constraints from your content view (the UIView inside the scrollview).
Then you can add all the objects that you need to add to the content view and set the height of the content view according to the height of the content.
So lets say that you calculated a height of 1000 for the content of the objects in the scroll view. You would then need to set the frame of the content view like this:
contentView.frame = CGRectMake(0,0,scrollView.frame.size.width, 1000);
And don't forget to set the contentSize for the scrollview so that the scrollview knows how much room it needs to scroll.
Just now found the answer with removing any autolayout constraints, for content view we have to set constraints like below:
Top, bottom, left, right
Align CenterX - here we have to set the content view height then for that constraint we have to set constant as scrollview content size height
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 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.