How can I make a multiline label in a UITableView? - iphone

How can we make the text in the label of a table view go to the next line?

//This allows for multiple lines
cell.textLabel.numberOfLines = 0;
//This makes your label wrap words as they reach the end of a line
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
Also, if you want your label to have more room for such multiple lines, you probably should allow for table rows with greater height. You can do this either by overriding
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
and returning your custom height for each row there, or by specifying your table's rowHeight property, giving the common height of each row.

Try adding "\n" in the label, eg:
#"Hello,\nworld!"

you can try to use cell with subtitle( initWithStyle:UITableViewCellStyleSubtitle ). if it is not exactly what you want, you can customize your cell by adding UITextView(or, maybe, several UILabels) to it as a subView(s).

Related

Remove spacing between UITableViewCells

I have UITableViewCells in the same section which have gaps between them. I coloured each cell's contentView background and did an NSLog to show that it's the same height as the cells.
Still, there's a gap between them. They're definitely in the same section as each other. Any ideas as to what could be causing the gap?
I'm not sure if you have used this:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 78;
}
And Checked that the Cell really is 78(just for arguments sake) in IB.
And then use:
tableView.sectionHeaderHeight = 0.0;
And set the style of the tableView:
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
And the last solution I've bumped into over the years is that sometimes you need to extend your background image with a pixel for some reason. I don't think this is a good solution at all, cause it doesn't really address the real problem, but rather puts a crappy bandaid on it.
cellFrameBackground.size.height += 1;
have you tried setting seperator style to none?
tableview.separatorType = UITableViewCellSeparatorStyleNone
If you are talking about a 1 pixel gap, that is the cell separator. You can remove this by setting a property on the table view:
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
If you wanted to change the color of that separator use the separatorColor property.
If you are talking about a gap bigger than 1 pixel, can you post a screenshot and your cell code?
To add to the set of great answers, sometimes you just need to extend the background height as mentioned by Leeloo:
cellFrameBackground.size.height += 1;
Then, make your cell clip to bounds:
cell.clipsToBounds = YES;
And, voila.

Adjusting row height correctly

Showing dynamic data in table cell make problem for me. I am using
[titleString sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(285,9999) lineBreakMode:UILineBreakModeWordWrap];
function for calculating the size now according to size i need to adjust row sizes. but it is inconsistent, Some time it give size(242,18) and (40,18) (showing width,height). when it gives more width for same height the it breaks in two line text and inconsistency begins. if i take less height then it overflow the text and if less in height then some time left a huge white space.
please help me and suggest some proper way for doing this.
you code seem me correct , there is only one place for modification left in your code that would be use CGFLOAT_MAX instead of 9999.
And Also check the lineBreakMode property, Assign numberOfLines With zero.
label.numberOfLines = 0;
label.lineBreakMode = UILineBreakModeWordWrap;
There is delegate method as follows
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == theRowWhereUwantToIncreaseTheSize)
{
return 105.0f;;
}
}

How to limit the number of cells UITableview displays?

Im using a tableview to display some information in a quiz app that Im working on. My question is how do i make the tableview only show the number of cells that I need. Ive set the number of rows delegate method like this:
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 5;
}
but at the bottom of the table view are empty cells that are not needed. If I set the tableview style to grouped I get 5 cells and no empty ones below them. Ive seen that other people have done this but cant seem to work it out. I was wondering if they have somehow added a custom view to the table footer to cancel the empty cells out?
Any ideas or help appreciated.
If you do want to keep the separator, you could insert a dummy footer view. This will limit the tableview to only show the amount of cells you returned in tableView:numberOfRowsInSection:
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
In swift:
self.tableView.tableFooterView = UIView(frame: CGRectZero)
A much nicer method which doesn't require cell resizing is to turn off the default separator (set the style to none) and then have a separator line in the cell itself.
I was having a similar problem, how to show only separators for the cells that contain data.
What I did was the following:
Disable separators for the whole tableView. You can do that in the
inspector for the tableview in Interface builder or by calling
[yourTableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];.
Inside your cellForRowAtIndexPath where you populate your tableview with cells create a new UIView and set it as a subview to the cell. Have the background of this view lightgray and slightly transparent. You can do that with the following:
UIView *separatorView = [[UIView alloc] initWithFrame:CGRectMake:
(0, cell.frame.size.height-1,
cell.frame.size.width, 1)];
[separatorView setBackgroundColor:[UIColor lightGrayColor]];
[separatorView setAlpha:0.8f];
[cell addSubView:separatorView];
The width of this view is 1 pixel which is the same as the default separator, it runs the length of the cell, at the bottom.
Since cellForRowAtIndexPath is only called as often as you have specified in numberOfRowsInSection these subviews will only be created for the cells that possess data and should have a separator.
Hope this helps.
This worked for me - I had extra empty rows at the bottom of the screen on an iphone 5 -
In my case I needed 9 rows
- (CGFloat)tableView:(UITableView *)tabelView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return self.tableView.frame.size.height / 9;
}
You can implement heightForRowAtIndexPath: and compute the correct height to only show 5 cells on the screen.
Are you always going to have 5 rows? If it's a dynamic situation you should set the number of rows according to the datasource of the tableview. For example:
return [postListData count];
This returns the count of the records in the array holding the content.
The tableview is only going to display the number of rows and sections that you tell it to. If you're always going to have just a single section, DON'T implement the method below.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}
Without this the tableview will only have 1 section. With it, as you would imagine, you can specify the number of sections.
It is quite Simple. Just set the size of the popover like this:
self.optionPickerPopOver.popoverContentSize = CGSizeMake(200, 200);
Certainly you can adjust the size (200,200) depending upon the size of contents and number if rows.
Easy way would be to shrink tableView size. I.e. 5 cells 20 points each gives 100.0f, setting height to 100.0f will cause only 5 rows will be visible. Another way would be to return more rows, but rows 6,7 and so would be some views with alpha 0, but that seems cumbersome. Have you tried to return some clerColor view as footerView?
I think u can try changing the frame of the table view, if you want to adjust with the number of cells.
Try something like this:
[table setFrame:CGRectMake(x, y, width, height*[list count])];
height refers to height of the cell
As Nyx0uf said, limiting the size of the cell can accomplish this. For example:
- (CGFloat)tableView:(UITableView *)tabelView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat result;
result = 100;
return result;
}
implement these two methods in your UITableViewController:
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
if (section == tableView.numberOfSections - 1) {
return [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
}
return nil;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
if (section == tableView.numberOfSections - 1) {
return 1;
}
return 0;
}
In fact, these codes are telling tableview that you don't need to render the seperator line for me anymore, so that it looks the empty cells won't be displayed(in fact , the empty cell can not be selected too)

How to shrink the spacing between Cell Header and Cell Text in UITableView

Is it possible to shrink the spacing between a cell header and cell text? Looking at the example below I'd like the header to be closer to the top of the cell that contains the other text.
Sorry, I don't have high enough reputation to embed images.
http://www.freeimagehosting.net/uploads/6afdd58c2f.jpg
Just implement tableView:heightForHeaderInSection: in your controller and return your desired height.
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 50.0f;
}
I assume that you are using a standard cell style and textLabel. You could change the frame.origin of the label, or create a custom cell from a nib with the exact layout you prefer.
You need to use method heightForHeaderInSection for defining space between header & cell text.
You can also change it depending on different sections for eg. at some sections you may need to show more distance & under some, you don't want to show gap.
For such case you can use CGFLOAT_MIN which is 0.000001f.
Giving you an example, how you can use different section with different header heights
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if (section == 0 || section == 2)
{
return 55.0;
}
else
{
return CGFLOAT_MIN;
}
}
Hope it will help you.

How can I do variable height table cells on the iPhone properly?

My app needs to have variable height table cells (as in each table cell differs in height, not that each cell needs to be able to resize itself).
I have a solution that currently works, but it's kludgy and slow.
My Current Solution:
Before the table cells are rendered, I calculate how high each cell needs to be by calling sizing methods such as -sizeWithFont:constrainedToSize: on its data. I then add up the heights, allow for some padding and store the result with the data.
Then when my UITableViewDelegate receives the -tableview:heightForRowAtIndexPath: I work out which item will be rendered for that cell and return the height that I calculated previously.
As I said, this works, but calling -sizeWithFont:constrainedToSize: is very slow when you're doing it for hundreds of items sequentially, and I feel it can be done better.
So for this to work, I had to maintain two parts of code - one that would calculate the cell heights, and one that would actually draw the cells when the time comes.
If anything about the model item changed, I had to update both of these chunks of code, and now and again they still don't even match up perfectly, sometimes resulting in table cells that are slightly too small for a given item, or too large.
My Proposed Solution:
So I want to do away with the precalculating the cell height. A) because it breaks the MVC paradigm and B) because it's slow.
So my cell draws itself, and as a result, ends up with the correct cell height. My problem is that I have no way of telling the table view the height of the cell before its drawn - by which time its too late.
I tried calling -cellForRowAtIndexPath: from within -tableView:heightForRowAtIndexPath: but this gets stuck in an infinite loop, since the first calls the second at some point, and vice versa (at least this is what I saw when I tried it).
So that option is out of the question.
If I don't specify a size in the height for row delegate method, then the table view goes screwwy. The cells are the perfect height, but their x position is that of cells of fixed heights.
Messed Table Cells http://jamsoftonline.com/images/messed_table_cells.png
Notice how the bottom cell is the correct size - it's just overlapping the previous cell, and the previous cell overlaps its previous, and so on and so forth.
Also using this method, while scrolling there is some artifacting occurring which I think may be related to the reuse identifier for the cells.
So any help here would be gratefully appreciated.
Here's what I use. NSString has a method that will tell you the dimensions of a textbox based on the font information and the height/width constraints you give it.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *text = [self getTextForIndexPath:indexPath];
UIFont *font = [UIFont systemFontOfSize:14];
CGSize size = [self getSizeOfText:text withFont:font];
return (size.height + 11); // I put some padding on it.
}
Then you write a method pull the text for this cell...
- (NSString *)getTextForIndexPath:(NSIndexPath *)indexPath
{
NSString *sectionHeader = [self.tableSections objectAtIndex:[indexPath section]];
NSString *sectionContent = [self.tableData objectForKey:sectionHeader];
return sectionContent;
}
And this is to get the size of the text.
- (CGSize)getSizeOfText:(NSString *)text withFont:(UIFont *)font
{
return [text sizeWithFont:font constrainedToSize:CGSizeMake(280, 500)];
}
Just a thought:
What if you had, say, six different types of cells each with their own identifier and a fixed height. One would be for a single-line cell, the other for a two-line cell, etc...
Every time your model changes, calculate the height for that row then find the nearest cell type that has height closest to what you need. Save that celltype identifier with the model. You can also store the fixed row height for that cell in the model so you can return it in the tableview:heightForRowAtIndexPath call (I wouldn't get too hung up on forcing it to calculate inside the cell class itself--technically it's not part of the cell drawing functionality and more something the tableview uses to decide which cell type to create).
At runtime, when asked to return a cell for that row all you need to do is create (or obtain from the cell cache) a cell with the celltype identifier, load the values and you're good to go.
If the cell height calculation is too slow, then you could pull the same trick the tableview cache does and do it only on-demand when the cell comes into view. At any given time, you would only have to do it for the cells in view, and then only for a single cell as it scrolls into view at either end.
I realise this won't work for you due to the infinite loop you mention, but I've had some success with calling the cells layoutSubViews method
Though this may be a little inefficient due to multiple calls to both cellForRowAtIndexPath and layoutSubViews, I find the code is cleaner.
-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCell *cell = (MyCell *)[self tableView:tableView cellForRowAtIndexPath:indexPath];
[cell layoutSubviews];
return CGRectGetHeight(cell.frame);
}
And in the layout code:
- (void)layoutSubviews
{
[super layoutSubviews];
//First expand the label to a large height to so sizeToFit isn't constrained
[self.myArbitrarilyLengthLabel setFrame:CGRectMake(self.myArbitrarilyLengthLabel.frame.origin.x,
self.myArbitrarilyLengthLabel.frame.origin.y,
self.myArbitrarilyLengthLabel.frame.size.width,
1000)];
//let sizeToFit do its magic
[self.myArbitrarilyLengthLabel sizeToFit];
//resize the cell to encompass the newly expanded label
[self setFrame:CGRectMake(self.frame.origin.x,
self.frame.origin.y,
self.frame.size.width,
CGRectGetMaxY(self.myArbitrarilyLengthLabel.frame) + 10)];
}