UITableView Auto-Layout Flexible Height - ios

I have following design.
Am using AutoLayout to make every thing flexible. In this design i have a UIView which is Gray in Color as showing in image and a UITableView below UIView. Some times i have to show this UIView and some times i have to hide this Gray UIView.
My problem is when ever i hide UIView, UITableView is not fixing its height. I don't want to hard code in .m file. Is it possible AutoLayout take care of this issue. I have these constraints as below image. Am i missing any constrain.
When i try to change UIView height, UITableView is not moving up and showing some orange constraints as show in image.

The contraints looks good. All you have to do to show/hide the gray UIView is change the height constraint constant.
To do this, create an IBOutlet in your controller for the constraint (you do this the same way you would for a UIView IBOutlet), and when you want to hide the gray view, set the constant property of the constraint to 0.
eg.
#interface MyViewController
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *greyViewHeightConstraint;
#end
and when you want to hide the view:
self.greyViewHeightConstraint.constant = 0;
To show the view again, you would have to save the "default" constant value after the storyboard is loaded (like in viewDidLoad for example), and set self.greyViewHeightConstraint.constant to this saved value.
Note also that these constraint changes can be animated.
The "orange constraint" you are seeing in Interface Builder is normal: it indicates that the view frame is not matching the constraints you set. You can then update the frame to respect the constraints, or update the constraints to match the frame.

Related

Layout challenge in xcode

Here is an image of what I want my page to do, this displays initially
and when Tips are selected, everything moves down accordingly,
This was created in android studio and it was simple, just have a layout that is "gone" and display when needed, everything would adjust itself.
However I am having a hard time trying to do that same in Xcode.
What I have tried to do was create a container view and link constraints so that when the size of the container view changes the label and switch would also move.
But when I add vertical spacing and then move the container it just increases the vertical spacing so it stays in the same position.
Add all of the Tip Type objects inside a UIView. Then add a height constraint on the UIView. You can set that height constraint to 0 when you want it to be hidden and 100 (or whatever height you need) when you want it to be shown.
Declare the NSLayoutConstraint:
#property (nonatomic, strong) IBOutlet NSLayoutConstraint *heightConstraint;
In storyboard, make your connection to the height constraint of your UIView.
Use the following code to hide the UIView:
heightConstraint.constant = 0;
Then to set the height to 100 (or whatever you want):
heightConstraint.constant = 100;

Autolayout issues when adding a new view into a hierarchy

I'm struggling big time with a couple of scenarios when i have a UIView with constraints applied via IB and adding a new UIView into it's view hierarchy. Here's how it goes:
I have a full screen UITableView with the following constraints applied so it scales nicely through all the resolutions of iOS devices:
Now i'd like to add a UIView above the UITableView acting as a sort-of toolbar.
Right now the only possible way i succeeded in adding this view is adding it on top of the TableView, so that it covers the top of tableview. What i'd like to achieve is the newly added UIView pushing table down so both are visible. I tried several things including adding a container view in IB just above the tableview however that didn't work at all.
So my question is: is there a way to dynamically edit, remove and add new constraints to the view hierarchy, ideally supporting animation?
You can create IBOutlets for a constraint, just like any view.
Each NSLayoutConstraint object has a constant property that you can set anytime in code (it's the value of the constraint).
So you would create both views on Interface Builder, and constraint the top of the table view to the bottom of the new view.
The new view will have a set height constraint, and you create an outlet to that height constraint to make that view appear or disappear in code.
There are other possible solutions but I think this one is the easiest.
The code would be something like this:
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *topHeightConstraint;
To set the value:
self.topHeightConstraint.constant = 60;
and to animate it:
[UIView animateWithDuration:0.6 animations:^{
self.topHeightConstraint.constant = 60;
[self.view layoutIfNeeded];
}];

How to remove space of hidden UIImage?

I'm stuck that I don't know how to remove spacing of hidden UIImage. Purpose is If flag is true, UIImage will be displayed and if flag is false, UIImage is hidden but space of this hidden image is still there.
I'm using Auto Layout.
If you are using Auto Layout and Storyboard you can set create an IBOutlet as a property of your Controller class. You then hook that up to the width constraint of the UIImage. In your code when the UIImage is hidden you set the IBConstraint to 0. When it is shown, you set the IBConstraint back to the normal width.
(in Controller.h)
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *constraintImageWidth;
(in Controller.m) (pseudo code)
if(hidden){
constraintImageWidth.constant = 0;
}
else{
constraintImageWidth.constant = 30;
}
There should also be a horizontal constraint between the left side of the label and the right side of the image set up in the Storyboard.
Here is where you would check the width box to add the width constraint.
Here is where you would connect the referencing Outlet to the IBOutlet on your controller
The easiest and most effective way to handle this is using Stack Views.
Insert both the images in a horizontal stack view and stack view will internally take care of the spacing. Additional properties like alignment, spacing can be tweaked as per requirement.
Keep in mind that you will have to re-establish the constraints between stack view and adjacent elements since once the views are added to a stack view all if its constraints are cleared

Stop autolayout from resizing my view

Using Storyboards I add a UIView with height of 5px.
At run time the height of that view is increased (could be up to 25px).
When the orientation changes, the height of the view is reverted back to the original 5px.
How can I prevent this? I want the height to remain at whatever it was prior to the orientation change.
Sure I could detect orientation change and then change it back but that looks sloppy because it shrinks then increases right away.
Edit: This may or may not be an autolayout issue. Or might just be the default behavior of storyboards.
Add a constraint fixing the height, you may also need to remove a constraint. If you show the code or explain how you're setting the constants in the first place can give a more detailed answer.
Other answer is to remove the constraint that stretching the size of your view, may be that you have conflicting constraints.
One more answer could be you need to adjust the priority of an other constraint perhaps one for spacing between views. Again more detail = better answer.
Overriding -layoutSubviews is the incorrect approach. If you're using autolayout you should adjust a view's height by modifying its constraints programmatically.
Make a property for your view's height constraint:
#property (strong, nonatomic) IBOutlet NSLayoutConstraint *heightConstraint;
I put IBOutlet there since you said you're making the constraints in a storyboard. Just drag the height constraint to that property to connect it. (You could also create the constraint programmatically, in which case you wouldn't use IBOutlet.)
Then, whenever you want to change the height:
self.heightConstraint.constant = 25;
The solution to the problem is to sublcass UIView and override -(void)layoutSubviews
In -(void)layoutSubviews is where I set my desired height

Change height constraint programmatically

I want to change the height constraint of a UITextView programmatically so I set the constraint as an outlet in my controller like this:
#property (strong, nonatomic) IBOutlet NSLayoutConstraint *descriptionHeightConstraint;
To change it I do the following:
self.descriptionHeightConstraint.constant = self.description.contentSize.height;
This works if I do it in viewDidAppear but the problem with this is that I can see how the height changes after the view displayed which is not very user friendly so I tried doing it in viewWillAppear but didn't work there, the height doesn't change. Calling setNeedsUpdateConstraints after changing the constraint didn't work either.
Why is working in viewDidAppear and not in viewWillAppear? Any workaround?
Thanks in advance!
Try setting the constant in viewDidLayoutSubviews instead.
Note that using the text view's contentSize property to set the text view's height does not work in iOS 7. See https://stackoverflow.com/a/18837714/1239263

Resources