Background:
I have a normal UIView in Storyboard (called statusView) which has a height of 30, and four constraints pinned to the leading, trailing, top space to the superview, and bottom space to the view below it.
Problem:
My goal is to alter the height of statusView, including animating the frame changes when the user performs an action. As such, statusView could be as short as 0 or as tall as 100.
My expectation is that, given statusView is constrained to the superview and its nearest neighbor below, it should automatically "push" the views below when I alter its height.
Just to test, in viewDidAppear, I call the following:
self.statusView.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 100.0)
self.statusView.setNeedsDisplay()
Issue: However, the height of 30 remains for statusView, despite me setting it to 0.
Edit: posted Storyboard settings
This is the setting for statusView:
If you are using autolayout and want to set an explicit height for a view in your hierarchy, you should use autolayout to do it. I am assuming there is a height constraint set up in interface builder.
Create an IBOutlet for the constraint and link it up in interface builder.
#IBOutlet weak var statusViewHeightConstraint: NSLayoutConstraint!
Then, assuming this is just a size constraint with a constant for the height, just change it in your code:
statusViewHeightConstraint.constant = 100
You can animate this change by wrapping a layout call in an animation block right after modifying your constraint(s). Something like this:
UIView.animateKeyframes(withDuration: 0.2, delay: 0.0, options: [.beginFromCurrentState, .calculationModeCubic], animations: {
self.view.layoutIfNeeded()
}, completion: nil)
Related
I'm using swift to build an application. I want to add some content to my view controller using storyboard.
I already put everything inside the scrollview and set the specific height, but however when I run the application, the scrollview always set longer than the button in the bottom of the view
I want the scroll view stop right after the button
Please kindly help me how to solve this problem
thank you
after scrolling
for your information, please ignore the white space between 'critics' and submit button, because actually there's UITextView between them but not visible (still try to add some border)
these are my storyboard preview
1) ScrollView Contraints
2) ScrollView -> contentView Constraints to scroll View same as above image
3) now ContentView width and Height Constraints to main View [SuperView in which ScrollView is embedded] and constraints will be as follows.
4) now click on the EqualWidth to View [Third constraint from top]and edit it as in step 6
5) contentView Width Contraint
6) ContentView Height Constraint // set priority [must] . here you need to change the first item and second item in the menu to as shown First as - ContentView.Height and second as - View.height and set priority to 250 after this a dotted line will appear in storyboard along the contentView
7) now add the content like [UIView, labels, textfields] in contentView and add constraints as Top upperMost view top space to contentView [like I have]DoubleRight imageView
and constraints for my DoubleRight imageView are
look for the Top space margin its given a top space 20 points
and same you need to do for the last item you will be adding in ContentView like I have uiView
add bottom space from this respective view to your superView[ContentView] and my constraints are:
after you had initialed all these steps results will be as Expected for every Screen size no need to change height additionally for screen sizes
Note : - [all the views must be connected to each other with top and bottom parameter]
like Flow will be
View1 - top to contentView and bottom to View2
View2 - top to View1 and bottom to view3
View3 [Last view] - top to View2 and bottom to contentView as shown
using uiView, uiimageViews their heights must be fixed
It may be helped
your_scrollView.frame = CGRect(x: 0, y: 0, width: 375, height: 667)
your_scrollView.contentSize = CGSize(width: 375, height: 1000) // You can set height, whatever you want.
You can try :
your_scrollView.frame = CGRect(x: 0, y: 0, width: 375, height: 667)
your_scrollView.contentSize = CGSize(width: 375, height: self.view.frame.size.hight)
I am trying to conditionally make a UILabel at the bottom of my view controller hidden and the view immediately above that adjust to fill the space.
The UILabel at the bottom of the view controller has a height of 120 and a constraint to the bottom of the view controller of 0. The view above it has a constraint to the bottom of the view controller of 120.
When I make the UILabel hidden and change the value of the view above it to the the bottom of the view controller to 0 (named viewBottomConstraint), the UILabel disappears but the view above it remains where it was.
Instead of changing the label to hidden, just change the height constraint!
You see setting the property to hidden has no effect on the nearby views but changing the height to 0 and calling layoutIfNeeded, updates all the constraints related to that particular UILabel and lays out all the views.
You need to set the height constraint to 0 of the UILabel. Do this by dragging an outlet of the height constraint from your storyboard to your UIViewController and then just:
heightConstraint.constant = 0.0
UIView.animate(withDuration: 0.3, animations: {
self.view.layoutIfNeeded()
})
I have created a storyboard as in the image. In that I have set the vertical spacing between the red view and tableView is around 20. Its working good.
But when i tried to change the height of red view then the tableview should comes up with the constraints I added but the table view is remained constant at the same place.
I used the following code
redView.frame.size = CGSize(width: 1008, height: 0)
self.view.layoutIfNeeded()
Whenever you are adding a constraint to any object on storyboard then onwards that object's frame will be maintained by autolayout engine. This is the primary design principle I guess. In this case what you can simply do is that just make an outlet of the desired constraint which you want to update and update that constraint within your code. For your understanding I am attaching a screenshot.
Now after making a constraint outlet it must look like as follows.
#IBOutlet weak var containerViewHeight: NSLayoutConstraint!
Now to update the height you just have to do one thing.
containerViewHeight.constant = 0
In my opinion if this update is not working inside viewDidLoad or viewWillAppear then please update inside viewDidLayoutSubviews because when viewDidLoad get called then iOS doesn't apply the layout properly.
In my case what I will do is -
override func viewDidLayoutSubviews() { //This ensures all the layout has been applied properly.
super.viewDidLayoutSubviews()
containerViewHeight.constant = 0
}
Note: - To achieve some nice animation effect during layout changes you can apply this constraint update inside an UIView animation block like as follows. But remember, to see the effect nicely you have to call this after presenting the view properly like after viewDidAppear etc.
UIView.animateWithDuration(1.0, delay: 0.2, usingSpringWithDamping: 8.0, initialSpringVelocity: 1.0, options: UIViewAnimationOptions.CurveEaseIn, animations: {
containerViewHeight.constant = 0
self.view.layoutIfNeeded()
}, completion: nil)
Sorry for any mistake.
Update/Edit is most welcome.
Hope this helped. Thanks
You should be using Autolayout to manipulate the redView's height. Modifying its frame's size is not Autolayout. Modify its height constraint (if it exists)
You need to either use constraints or changes to frames! You cannot do both!
What you need to do is to make an outlet reference to your constraint and change its constant-value instead.
If you placed the code in viewdidload or viewwillappear, you will find issues like this. You need to put the code after all the constraints are loaded.
Also, make an object of the height constraint and name it for example redViewHeight.
and change its value by: redViewHeight.constant = 0
It will work!
Replace the constraints for the views with the following.
Redview
Top constraint to ParentView
Leading Constraint to ParentView
Trailing constraint to ParentView
Height Constraint
TableView
Top constraint to RedView
Leading Constraint to ParentView
Trailing constraint to ParentView
Bottom constraint to ParentView
Now wire an IBOutlet for the HeightConstraint of RedView and modify its constant value. The UITableView will adjust its height as desired.
Couldn't find any answer for this, or am I missing something...
In iOS with autolayout on storyboard. If I have a UIView with some controls in it, depending on what the user clicks, the subviews are resizing. Can I somehow have the superview resize to the content?
In my app I have a view, but if a button is clicked subview is hidden I want the superviews height to decrease to exclude the hidden view. I can hook up the height constraint and handle it programatically, but it would be nice to handle it automatically....
Is there a way?
Can I assume that you have some constraint that relates the size of your superview to the size of your subview?
If so, all you will need to do to resize your superview when you hide the subview, is change the height constraint of your subview to 0 (auto layout won't care if your subview is hidden or not, it only takes into account constraints).
you can try something like this:
You can try putting this code to your buttonAction
yourView.frame = CGRect(x: anotherView.bounds.minX, y: anotherView.bounds.min, width: anotherView.bounds.width , height: anotherView.bounds.height)
in this case "yourView" will change its size to "anotherView".
yourView.frame = CGRect(x: anotherView.bounds.minX, y: anotherView.bounds.min, width: anotherView.bounds.width , height: anotherView.bounds.height / 2)
This example will change the height to 1/2 of "anotherView" frame.
Hope it will help you a little bit.
I was missing something.. 😄
What I didn't get was that the view will resize for its contents if you don't set a height for it and have the content have a constraint for the bottom of the view.
So I ended up setting the height of the hidden control to 0, and the bottom control constraint to parent bottom.
I got frustrated with AutoLayout so I decided to disable it and just set the positions and sizes of the elements in my view programatically. I tried this:
func setScrollViewBounds() {
var windowFrame = self.view.frame;
var scrollerHeigth = (windowFrame.height/100)*15
BottomScroll.frame = CGRect(x: CGFloat(10), y: windowFrame.height-scrollerHeigth, width: windowFrame.width-20, height: scrollerHeigth);
TopScroll.frame = CGRect(x: CGFloat(10), y: BottomScroll.frame.maxY-10, width: windowFrame.width-20, height: scrollerHeigth)
}
Im trying to set the two scroll views (TopScroll and BottomScroll) to be at the bottom of the page and have one be on top of the other. This however doesn't seem to do anything. Any ideas why?
I'm calling the function in ViewDidLoad().
TopScroll and BottomScroll are IBOutlets.
Apply constraint following order
Put your subviews in UIView Object(Which will subview of ScrollView).
Select Both ScrollView and UIView
Go->Pin->Equal Width.(Not Equal Height)
Select UIScrollView Go-> Pin uncheck Constraint to Margin and give Top,Bottom,Left,Right constraint.
Now Select UIView(Subview of UIScrollview say contentView) control click contentView to Main View(Default controller's View) and select Leading,Trailing,Top,Bottom constraint.
Finally Select contentView Go-> Resolve Auto-layOut issue -> Reset to Suggested constraints.
Constraints for subview of ContentView as usual with respect to contentView. use viewDidLayoutSubview for setting content-size to UIScrollView.