I have a UITableView. The height and content of each cell of the table view varies, depending on the data feeding to the cell. To give an example - some might have pictures, some might only have text; some might have 1 picture, some might have more than 1 picture. So, I am thinking about subclassing the UITableViewCell so I can use the subclass in other table views that I might have.
Is there some sample code that I can follow to achieve that goal - subclassing UITableViewCell, varied content, varied height?
This has been asked many times.
Also, you don't need to subclass to get variable row height, nor to put custom controls into the cell, but for the latter case subclassing may be convenient.
Related
My tableview add blank space to the end of the cells.
I don't know why, how do I fix this problem? (For ex I have 50 cells, two of them you can see here because this is last two cells)
Hard to know without seeing your code, but because your cells have varied heights, you should probably start by implementing tableView:heightForRowAtIndexPath:
If you end up wanting more manual control over the table's height, take a look at its contentSize property.
I would like the Subtitle-style cells in my iOS 8 table view to resize automatically in height to allow subtitle content of any number of lines. And, I would like to accomplish this without using custom cells, if possible. That is, I would like to use the "canned" prototype cells that are available when dragging a new TableViewController to the story board.
I have found that this is easy to do with Basic-style cells: that is, prototype cells with Style set to "Basic" so that there is just one label in the cell -- "Title", by default. This is the label that is accessible by cell.textLabel!.text in code. If I set that textLabel's number of lines to 0, and add the two lines below to viewDidLoad(), then the cell heights resize automatically:
tableView.estimatedRowHeight = 144.0
tableView.rowHeight = UITableViewAutomaticDimension
All without having to define a custom cell or muck around with auto-layout or constraints. (In fact, I find it's not possible to add constraints to a canned prototype cell.)
But if I change the cell Style to "Subtitle," so that there are two labels in the cell -- textLabel and detailTextLabel in code -- then the cells do not automatically resize in height, even after setting both (or either) line numbers to 0 and playing around with different estimatedRowHeight values.
Am I missing something, or is it not possible to automatically resize cell height without a custom cell?
Thank you!
or is it not possible to automatically resize cell height without a custom cell?
Yes, it is not possible. And the reason is the reason that you gave. The automatic-resizing-cell-height feature depends upon internal constraints. But, as you have rightly said:
it's not possible to add constraints to a canned prototype cell.
However, note that you can accomplish what you want without supplying a cell subclass (though personally I like supplying one). You can just design your cell, constraints and all, right there in the prototype cell — the Custom prototype cell.
I'm looking to change the number of columns my tableview has without subclassing it. Any suggestions?
I think you can find your happiness here: http://usxue.is-programmer.com/posts/14176.html
With that you can create a Grid and have multiples columns
If you don't need to select individual columns the you could just subclass UITableViewCell to make it LOOK like it has more than one column.
Doing this without subclassing anything would need to be done as follows:
1) Place a UIScrollView in the view.
2) Put n amount of UITableViews embedded in the UIScrollView where n is the amount of columns desired.
3) Turn scrolling off in all of the UITableViews.
4) Make all of the UITableView frames equal to that UITableView's contentSize.
5) Set the UIScrollView's content size equal to the largest UITableView's frame.
I have not tested this because I would definitely recommend subclassing either UITableView or UITableViewCell, but this would be one way of doing it.
I'm creating a custom cell in the cellForRowAtIndex function and filling it with my dynamic text. The height of the cell is variable based upon this text so I need to user the heightForRowAt function, but in that function I don't have the cell. I can create a new one and fill it with the text and then call my calculateHeight function on it but then I'm creating 2 cells for each row.
Anyone have a better method? Cache the cells yourself in the cellForRow function in a dictionary by row index and use that? Is cellForRow called before heightForRow?
I've managed to crash Xcode4 twice so far playing around with this so am hoping someone has done this already.
tableView:heightForRowAtIndexPath:
is called before
tableView:cellForRowAtIndexPath:
Creating two cells is a possible solution, but creating two cells isn't a very effective method. However, you don't need the cell to calculate the height; All you need is the string.
You'll probably want to use
sizeWithFont:constrainedToSize:
on your string to calculate the height.
I could provide details on how to do that, but you should be able to figure it out from reading the documentation.
What you do is you make a class method on your custom cell (for instance), which knows the values of how things (statically sized things) will be set, and does some math to determine given the offsets of the text view for instance, it can tell you how big the cell needs to be after calculating how high your string will be given a font.
Question
How can you detect when the Table View is done drawing the cells?
Issue
I got two labels within the contentView of an UITableViewCell. The size of these labels are dynamic. I was able to do so by subclassing UITableViewCell, in the drawRect method I adjust the frames of the two labels depending on their content. Now I want to align all the second labels.
My Thoughts in Steps
Determine the content in the table view and let it load automatically.
Run through the table view cells and determine the x position of the second label within the UITableViewCell that is the furtherest away.
Store this x position and when any cell is drawn use this x position to place the second label.
The problem is that if I use the following code:
for (int row = 0; row < [self.tableView numberOfRowsInSection:section]; row++) {
UITableViewCustomCell *cell = (UITableViewCustomCell *)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:0]];
NSLog ([cell.labelTwo description]);
}
The second label has not yet been drawn, meaning I can't determine the size of the frame and thus can not find the proper x position to align all second labels.
I have tried subclassing the UITableViewController and looking at events such as viewDidLoad and viewDidAppear unfortunatly also in these events the cells aren't drawn yet.
What I Want ...
What I want is for the table view to draw the cells at least once so I can determine the sizes of the labels within the table view cell. I thought to accomplish this by looping through all the cells with cellForRow, but although it successfully returns the cell the content is not drawn yet meaning the frame remains with a width of zero.
Does anyone have a solution?
Thanks in advance,
Mark
Try calling sizeWithFont: on the contents of these labels to get the max width before you draw anything. You should be able to use it later in your cellForRowAtIndexPath: to adjust the width as you need.
I would recommend you reconsider using UITableViewCellStyleValue2 cells instead and attempt to configure the textLabel and detailTextLabel. I had a similar situation and this is how I did it.
First off, you really ought to just pick an explicit, fixed position at which the first label ends and the second one begins, based on what you know about the minimum and maximum lengths of the text that will be put in those labels. That would eliminate this problem entirely.
But if you want a solution: use the sizeWithFont: method or one of its cousins (see the Xcode docs). Specifically, loop through the values that will go in the first labels, apply sizeWithFont to each, and keep track of the largest width you see. (I'm assuming you have access to the values before they go in the cells; since they're dynamic, they must be passing through the table view controller, no?)
Now you have the value you seek, without having to perform the extremely wasteful operation of creating a bunch of cell objects and never using them for their intended purpose.
I think what you need to do is to add a viewController to the have the UITableViewController control the UITableViewCell itself so that you can capture the events of the labels loading. The viewController will have references to both labels so it can adjust them accordingly in response to -viewDidAppear.
I've never done this but a UITableViewCell is a view like any other so you should be able to set up a controller for it. You might need to manually activate the controller since you have no navigation controller to do it for you in this context.