I've a tableView with custom cells.
Each cell has different interface, elements. All they have different sizes.
Each cell has different type of elements and their count.
All these elements are created dynamically, so I'm creating them, making their frames and adding as subviews.
So the problem that heightForRowAtIndexPath executes before cellForRowAtIndexPath where I'm creating the row and constructing its interface and I don't know how to pass calculated height to heightForRowAtIndexPath
How can I count row height before and pass its value to heightForRowIndexPath for correct drawing of my tableView?
If your cell view is really very complex and every component's height are depending on data source. You can try to create the view in heightForRowIndexPath method and then cache the created view to a dictionary in your view controller and use it directly in cellForRowAtIndexPath. In this way you only need to create the view once when user scrolling the table. If the datasource is not changing very frequently, you can reuse the cached view in heightForRowIndexPath as well.
And if the tableview has a lot of rows, you should return an approximate value for height in estimatedHeightForRowAtIndexPath to speed up the loading process of the view controller. Otherwise during loading tableview, it will try to calculate all row's height which may requires a lot of time.
But I really don't think your cell would be so complex. If only some UITextLabels that depends on datasource for the height, you can simply only calculate the height for the label, then add it to other components' height which is fixed.
You really should consider subclassing UITableViewCell and adding your custom logic inside your subclass.
Starting from there, you'll have such options:
Create static method in your cell that will receive all data necessary to draw your cell (e.g heithtForCellWithFirstString:secondString:accessoryImage etc) and calculate height using string size computation methods. Use this method inside heightForRowAtIndexPath.
Use autolayout for laying out subviews of your cell and then set table view's row height property to UITableViewAutomaticDimension. This way you won't need heightForRow delegate method at all. There are plenty of tutorials on this, for example: http://www.raywenderlich.com/87975/dynamic-table-view-cell-height-ios-8-swift
Try to create a subclass of UITableViewCell.
All elements created by you put inside UIView, which is put in a cell.
Create three NSLayoutConstraint, one from UIView.top to top of the cell, the second from UIView.bottom to the bottom of the cell and the third - the height of the UIView.
In the viewDidLoad method of tableViewController set row height as the UITableViewAutomaticDimension
:
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.rowHeight = UITableViewAutomaticDimension
}
In a subclass of UITableViewCell create a method that will calculate the height of the cell and change NSLayoutConstraint, which sets the height of the cell. For example:
:
func adjustHeightOfInnerView() {
let height = 100
self.myInnerCellViewHeightConstraint.constant = height
self.contentView.setNeedsUpdateConstraints()
}
In the method cellForRowAtIndexPath call the adjustHeightOfTableview:
:
func tableView (tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as! myTableViewCellSubclass
cell.adjustHeightOfTableview()
return cell
}
Related
I have created an expandable tableview by separated with multiple sections. Because this tableview is inside a container view, so I need to update the container view size every time the tableview expand or collapse.
I update the container size with tableview.contentsize.height but I found out the content size are different when its expanded or collapsed.
For e.g, lets say there are 4 sections, if I collapse the 3rd and 4th sections the tableview will return me height of 200. Meanwhile if I expand the table just 1st and 2nd section while 3rd and 4th is collapsed, the content size height is more than 200.
I find it very frustrated why the program is giving me such confusing information, because I need a proper content size height to update the container view. Anyone here can enlighten me?
Instead of using the contentSize try calculating the height on your own. It'll be much easier if every cell is the same height. Let's say they are all 50 height and there is 1 row in section 1 and 3 rows in section 2. (1 + 3) * 50 = container height. Obviously if you have sections and insets you will also need to include that into your calculation.
If your cells are different heights, just call the table views cell height delegate to get the relevant height.
If this doesn't work for you then please be more descriptive and add some code.
The behavior of content size that you've described is correct. If you want to know the height of the UITableView you should look at it's frame, not at it's content size.
I'm not sure why you need a container view for the table view, you can layout it like the simple UIView, then you'll have one less problem, just change the tableView frame.
Update:
After reading comments i see that you want tableView inside of tableViewCell. Most part you'll have to do yourself, but i can help you with UITableViewAutomaticDimension.
Try adding this to your viewController:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
override func tableView(tableView: UITableView, estimatedHeightForRowAt indexPath: NSIndexPath) -> CGFloat {
return 44//approximate cell height
}
The main thing is to set constraints properly in interface builder. And remember that constraints won't change the height of the cell on builder, you may have to do it yourself in the Size inspector. Anyway if you won't - it will be resized during the build.
Tableview has three types of custom cells with dynamic height. I want to set the row height using like tableView.rowHeight = 100 in cellForRowAtIndex() method.
Is this appropriate?
1.Define auto layout constraints for your prototype cell
2.Specify the estimatedRowHeight of your table view
3.Set the rowHeight of your table view to UITableViewAutomaticDimension
Do these code in viewDidLoad
tableView.estimatedRowHeight = 68.0(actual height of your prototype cell)
tableView.rowHeight = UITableViewAutomaticDimens
No, that is not how you need to do it. Never make any attempt to set any table attributes inside the cellForRowAtIndexPath method. Just create and return a cell.
If your cells have varying heights, simply implement the heightForRowAtIndexPath method and return the appropriate height for a given indexPath.
If all rows have the same height, then set the table view's rowHeight property in viewDidLoad or other appropriate place.
I have a TableView with 2 prototype cells in it. I want one of them to be static (call it header cell), and the other one to be dynamic (call it description cell).
So I set TableView cell to Dynamic Prototypes and 2 for prototypes cells). I have also set up the TableView and increased prototype cells; and put dummy data for seeing them working.
However, whatever I have done I couldn't resize the Header cell.
First, in Storyboard, I tried changing Row Height for the Header Cell (and I ticked the 'Custom'). It seems like changing the height of the row in the Storyboard; in fact it doesn't after the build.
Secondly, this width and height bit seems disabled.
It's also same for the Content View just under the Header Cell. Width & Height adjusting part is disabled.
By the way, everything is same for the Description Cell. I tried adding it a row height, and it seems like changing in the Storyboard, but after build, no luck. It is just behaving by itself.
I should also highlight that it's giving a bit more room for Description Cell which I return cell.textLabel?.text = "BlaBla" (so it has to write the text itself); but for the other cell where I am dragging/dropping on Storyboard, it just squeezes the height.
What may I be doing wrong? What do you think do I miss?
Edit: (I have a Navigation Bar at the top)
How it looks on Simulator:
How it looks on Storyboard:
As you can see it's narrowing the Header Cell (so messing the design), and increasing the height of Description Cell randomly.
If I can do it with heightForRowAtIndexPath, how should I use this approach for giving different height to 2 prototypes cells. (I want to have Header Cell to be static row height, but Description - Dynamic, or at least not identical height)
You're going to implement - tableView:heightForRowAtIndexPath: in your table view's delegate and return the height you'd like for each row.
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if indexPath.row == 0 {
return 100
}
return 44
}
I am creating an application with a Table view controller. I am following this tutorial link. Now my problem I want to change the height inside of the items. Each cell has two labels vertically. I set height for the row like this.
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if (indexPath == selectedIndexPath ){
return 200
}else {
return 100
}
}
How can I change the height of items inside of cell.
Edit 1:
In default label has only one line of text after clicked there is multiple line of text. So need to change the height of the label and the whole cell.
Edit 2:
Before click my cell I have like this.
After I clicked my cell I want like this:
Make the items in the call scale dynamically depending on the bounds size of the cell.
You can configure layout constraints to achieve that. You would set constraints, define margins etc. The label would scale depending on the height.
Alternatively you can do the layout manually, calculating and setting the frames in layoutSubviews method of the cell.
Here is a nice tutorial that might help you Dynamic Table View Cell Height and Auto Layout
So I want to make timeline content like instagram, I'm using custom cell on my uitableview. My problem is I already set the cell height to 345 on the storyboard but I get cell table like below:
and here is my custom cell on storyboard:
How can I fix it, so I can get the result like on my storyboard?
The reason that you are having this issue is you have probably set your Custom tableview cell's row height to 345 but that is not set as custom while your UITableview's row height is less than 345. So, what you need to do is go to storyboard and select the Table(UITableview) and set its row height to the maximum possible row height.
Let's assume that you are going to have two different kind of row heights. One with 345 and another with 325. As 325<345, you set your tableview's row height to 345.
Now, select the custom tableview cell and make its row height as custom and set that to either 345 or 325. In your case, it will be 345.
It should be good now.
However, more appropriate way when you have different cell size would be to use the delegate method for row height specification.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if(indexPath.row==0){
return 345;
}
else if(indexPath.row==1){
return 325;
}
else{
return 300; //a default size if the cell index path is anything other than the 1st or second row.
}
}
Use this delegate method:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 345
}
In your UITableViewController subclass, set self.tableView.rowHeight = 345. Might be a bug with storyboard heights not being translated.
You can set Table View Cell height here.