How to automatically set height of UICollectionViewCell to fit content - ios

I have a UICollectionView that has a bunch of cells that contain content of different heights. How can I go about having the cells automatically grow to be the height of their content?

I'm not sure if there is an automatic way of doing this like using UITableViewAutomaticDimension other than using autolayout constraints
What you could do is to create a constraint property
#property (nonatomic, strong) NSLayoutConstraint *heightConstraint;
Then calculate the content size of the cell after creating it and in updateConstraints update the heightConstraint constant
self.heightConstraint.constant = calculatedHeight;
Finally whenever you have updated the content call to setNeedsUpdateConstraints

http://code4app.net/ios/FBLikeLayout/54f17bdbe247418102a8f6e4
Here is a link that shows an example project with different size CollectionCell Heights.

Related

Change frame of UITableView as per number of rows in cellForRowAtIndexPath in Objective-c

I am resizing my UITableView as per its number of rows in cellForRowAtIndexPath:, that's why the next part of the UITableView was not visible, and for the part of the UITableView which is not visible, cellForRowAtIndexPath: is never called.
But I need to manage TableView frame according to number of rows, please suggest how can i implement this.
Thanks
If you are using autoLayout
To your UITableView add a leading, trailing, top and bottom constraint >=0. Also add a fixed height constraint with a priority of 750. Create an IBOutlet for this height constraint to your UIViewController. Now you can calculate your height using. This will allow your UITableView to only become scrollable once the total height exceeds your screen bounds.
//dataArray = array of your data source
tableViewHeightConstraint.constant = dataArray.count * rowHeight;
Now this height constraint will break as soon as the UITableView becomes scrollable so if you are adding the ability to delete the rows, you will have to create a new height constraint to the UITableViewas soon the number of rows of doesn't take up the entire screen bounds and update the new height constraint appropriately.
You can do using UITableView's content size property .
[tableView reloadData]; // you need to reload data first before set frame
tableView.frame =CGRectMake(tableView.frame.origin.x,tableView.frame.origin.x, tableView.frame.size.width, tableView.contentSize.height);

UiCollectionView in UITableViewCell

I'm trying, with no success yet, to add a UiCollectionView to a static UITableViewCell and have it resize the tableViewCell vertically as the numbers of items in the collection grows. Is this even possible or is there a better solution to this problem?
Add height constraint in collectionview through storyboard and declare an iboutlet of class NSLayoutconstraint in tablecell for that constraint. In your tableview cell data configuration code change the constant value of that property to collectionview's contentsize.height. This will force the collectionview to increase its height which interns will force the cell to increase its height.
You can call .contentSize on the collection view to get is't size, and set that size for the UITableViewCell size.

Update constraints of other elements when UITableView height change

I have a UITableView of which I am defining height as 200 in autolayout. Based on that I am laying out other elements below it like UITextField etc. After that in run time I am fetching data from server and populating in UITableView due to which i am updating UITableView's height based on its content size. Following code I am using for it
self.myTableView.frame = CGRectMake(0 , 0, self.myTableView.frame.width, self.myTableView.contentSize.height)
But due to this, all the elements placed below UITableView still appear at same location which they were while laying out in Autolayout. Means change in height of UITableView makes no difference to them. Following image depicts this problem. What could be possible solution for this?
Here you can see, text fields are getting overlapped on tableview at run time. I am using Swift 2 in Xcode 7.2
If you have all required constraints to your table view and other view.
Don't change the frame of TableView to change height of it.
Instead create IBOutlet of height constraint of your tablview.
e.g. say IBOutlet name is constraintTableViewHeight,
then you can the the hight easily.
constraintTableViewHeight.constant = yourNewHeightValue
//update all constraint of your view and its inner view
self.view.layoutIfNeeded();
Refer Image to create IBOutlet for your height Constraint.
Take IBOutlet of NSLayoutConstraint for tableView Height and set its value not set tableview frame it's not working if you are already given constraints for tableview so change tableview hight constant
like if you take tblHeight for tableView height then set tblHeight.constant = self.myTableView.contentSize.height
You have to create an outlet connection for your table view height constraint:
#IBOutlet var heightConstraint: NSLayoutConstraint!
and when you want to change table view height, you can change the constraint value like this:
heightConstraint.constant = newHeightValue
self.view.layoutIfNeeded()

Frame Resizing using AutoLayout

I have an UIView inside which i have a UIButton. I am using auto layout. Now I want to reduce the height of the UIView. How should I do it ? On reducing the height of the UIView , the UIButton inside the view should also move up at the same time. How can i do this using Auto Layout ?
You can create IBOutlet for height constraint of you view and you can change value for it.Just check how to create.
Now use the code below to set height of you UIVIew
heightConstraintOfView.constant = DYNAMIC_HEIGHT;

Is it possible to subclass UITableView and make it have an intrinsic content size for its height based on the number of cells?

I want my UITableView to only be as tall as it needs to be, as it floats above the main UIViewController's view. If I hardcode a height of 200 and theres' only one cell in the table, it looks silly.
I'm aware in my view controller I could monitor the table view and define the height of it based on the number of cells it has, but the height is a property of the view, and for MVC it doesn't make much sense for the controller to be actively managing a view's height.
Is it possible to have a UITableView subclass, and have it define an intrinsic height based on the number of cells it holds? So with Auto Layout I could add the subclass to my view, specify its width, center it vertically, and perhaps define a "less than or equal" height constraint saying to keep it smaller than 200pts. But for the most part have the intrinsic content size of the view define the height of the view automatically?
This would be just like a UILabel being able to be centered horizontally and vertically with some distance from the left and right, and have it grow and shrink vertically automatically.
Could I feasibly do this with a UITableView subclass?
You can do this easily by having the table view use its contentSize property to "know" how tall it needs to be. This value could be somewhat inaccurate if you're using estimated row heights, but it should be good enough. In this example, I gave the table view a height constraint (as well as width and centerY), and made an IBOutlet to it (heightCon). The only code needed was this,
#interface RDTableView ()
#property (weak,nonatomic) IBOutlet NSLayoutConstraint *heightCon;
#end
#implementation RDTableView
-(void)reloadData {
[super reloadData];
self.heightCon.constant = MIN(200, self.contentSize.height);
}
You would also have to override reloadRowsAtIndexPaths:withRowAnimation: and
reloadSections:withRowAnimation: if you're updating your table with either of those as well.
This feels like a chicken/egg problem you have with designing your UI. Sounds like you want to set the height of the floating tableview based on how many rows it contains * height per row, but the tableview doesn't know any of this information until its been drawn, ie [tableView reloadData] and the corresponding height for row delegate methods are called.
I'd suggest rendering the tableview offscreen somewhere, draw all the rows, sum up all the heights for each row, then present the view to the user with the appropriate CGRect.
When you (re)load data in your TableView, you can do this. The TableView will take only the height it needs
CGRect frame = youTableView;
frame.size.height = CELL_HEIGHT*[yourArray count];
if(frame.size.height > MAX_TABLEVIEW_HEIGHT)
{
frame.size.height = MAX_TABLEVIEW_HEIGHT
}
youTableView.frame = frame;

Resources