Problem in displaying properly in tableView cell by using label - iphone

In my application I parsed the data through NSXMLParser and made separate class to store that data from which i usually display the data. Everything works fine in simulator except the the title which is display in table cell with image. Images appears properly but the title not appear properly.
This is my code:-
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"TableCell3" owner:self options:NULL];
cell = nibLoadedCell;
}
NewsInfo *aNewsInfo = [appDelegate.newsArray objectAtIndex:indexPath.row];
titleLabel.text = aNewsInfo.title;
imageLabel.image = aNewsInfo.smallImageData;
return cell;
}
and in this way i configured my TableCell3.xib
Now i want my title data in 2 rows in label of the TableCell3.
I already used both the way through xib attributes settings or through code.
Code which i used instead of this xib attributes settings are:-
titleLabel.lineBreakMode = UILineBreakModeWordWrap;
titleLabel.numberOfLines = 2;
titleLabel.text = aNewsInfo.title;
Now Can any one help me to figure out this prob i want to display my title in two rows of the table view cell.
Thanks in Advance.
My Data is showing in this way...![enter image description here][2]
So i want to display this title fully it show's partially right now...
i want to display in two lines...

My guess is that you need to enlarge the label height.
Maybe the label height i not large enough to display 2 lines of text and that's could be the reason that you see only 1 line.
in interface builder try to enlarge the label height.
and maybe i am wrong ?
Good luck
Shani

Adjust frame of an UiLabel to have more space for two lines or decrease font size.

Related

UITableView showing more rows than specified in numberOfRowsInSection:

I want my tableView to show 6 rows with text in it, in this case "Example." As far as I can tell, I have my numberOfSectionsInTableView: and numberOfRowsInSection: set properly. See example code below:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
// Return the number of rows in the section.
return 6;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = #"Example";
return cell;
}
The problem is when you see the image below showing lines for rows that shouldn't/don't exist.
How do I get rid of the lines showing past row 6?
The generally accepted way of doing this is to add a footer view with a frame size of CGRectZero, as such:
[tableView setTableFooterView:[[UIView alloc] initWithFrame:CGRectZero]]
What this does is tell the table that there is a footer, and so it stops displaying separator lines. However, since the footer has a CGRectZero as its frame, nothing gets displayed, and so the visual effect is that the separators simply stop.
Swift Version
The easiest method is to set the tableFooterView property:
override func viewDidLoad() {
super.viewDidLoad()
// This will remove extra separators from tableview
self.tableView.tableFooterView = UIView(frame: CGRect.zero)
}
This is Because of Your Table-view Height. Weather you have Write
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
// Return the number of rows in the section.
return 6;
}
But its show rows According to Table-view Size. If you Dont want to show This extra Lines then Make UITableView Style Plain To Grouped.
Short and simple answer..
self.tableView.tableFooterView = [UIView new];
You could do something along the lines of:
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:7 inSection:0];
[self.mytableView cellForRowAtIndexPath:indexPath].hidden = YES;
Im sure there are some better ways but this is the first thing that came to mind.
If you're referring to the light gray lines that appear below the last row, that's simply the default way a UITableView draws the row separator.
You could try changing the Separator style in Interface Builder (see the images below) to see if one of those might be more to your liking.
You didn't say what you do want to see past the last row. If you just want to see the window background, then just embed your table view in a UIView that's just tall enough to show the number of rows you want to see. If you want to see more rows without scrolling, then you would have to adjust the size of that containing view based on the number of rows.
To programmatically remove it, use this:
[yourTableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
It's a lot easier to:
return numberOfSections + 1
return 0 rows in the final section
This keeps it simple!

iPhone: smooth scroll through the UITableView

I have a UITableView, and custom cells on it. On cell I have a UILabel, but before I set text to UILabel I did really hard work on text...like find the text in another text, highlight some words on it, and only then I set it to label. So when I scroll my list, it has delay because of this hard work. Any idea how to improve performance ? Maybe to do all hard work in another thread ??
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath {
static NSString *customCellIdentifier =
#"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
customCellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomTableRow"
owner:self options:nil];
if (nib.count > 0) {
cell = self.customTableRow;
}
}
self.myLabel.text = [self giveMeTheTextThatINeed];
return cell;
}
[self giveMeTheTextThatINeed] - did a hard work on text that takes some time.
Make a new thread for every cell. this thread calls [self giveMeTheTextThatINeed:indexPath], and resets the label(s) in the cell. I'm assuming you can't get your data any faster, so you want to maintain the scrolling in the table and spin the hard work out to the thread. When the thread is finished, update the cell. You see this a lot in cells with a thumbnail image where the thumbnail only gets uploaded after a while, and is blank or has a placeholder there first.
Any way for you to precompute the values you'll need? In other words, start doing your "hard work" (in another thread) when the app starts, and store it somewhere so that, if it's ready, you can just grab it when the table view asks for it. It's hard to answer without more detail about what the hard work is and how much data we're talking about.
I don't know about just doing the hard work on another thread as you suggested, since you still have to give something to tableView:cellForRowAtIndexPath:. I suppose you could return some kind of template cell at first, and then update it with reloadRowsAtIndexPaths:withRowAnimation: when the hard work is done.
I believe the method giveMeTheTextThatINeed needs to take the current cell as one of the parameters (or another parameter dependent on the cell content), e.g.: [self giveMeTheTextThatINeed:indexPath]. Otherwise you could store the text as an instance variable and set it in all cells from that variable.
So, with that in mind, the easiest way is to store the result of the computation in an additional dictionary, where indexPath (or the other parameter) would be the key:
self.myLabel.text = [self->myDictionary objectForKey:indexPath];
Now, you could either pre-populate that dictionary before the cells are drawn (e.g. in viewWillAppear), or cache them once they are calculated so that they are not recalculated when the cells are scrolled, e.g.:
NSString* calculatedText = [self->myDictionary objectForKey:indexPath];
if(calculatedText == nil)
{
calculatedText = [self giveMeTheTextThatINeed:indexPath];
[self->myDicationary setValue:calculatedText forKey:indexPath];
}
self.myLabel.text = calculatedText;

UITableViewCell - view showing data on top of data when being reused

I'm using a custom UITableViewCell. They load up great, but when they get reused instead of replacing the text in the labels, they are some how writing over the top of them. Any ideas how to stop this behaviour?
I assume I'm not reseting the view correctly before it gets reused. I'm currently empty the labels so they have just a blank #"" string. But I still get the old text plus the new (very messy).
I'm certain there's an obvious solution to this (presently i just don't reuse the cell, but this isn't best practice and is slow on old devices), so if someone can help I'd be very grateful.
Thanks
ED
As requested here is the method for amending the cell
static NSString *CellIdentifier = #"Cell";
TransactionCellView *cell = (TransactionCellView *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"TransactionCellView" owner:self options:nil];
cell = tblCell;
}
[cell resetCell]; // clears the labels
[cell setData:[dataArray objectAtIndex:[indexPath row]]; // replaces the data and updates the labels
return cell;
}
Solved this issue!!! Amazingly simple when you know what the problem is/was.
I was using IB and "Clear Graphics Context" was not selected on my UILabels. So that is why the next text was just overlaying the old.
THanks guys for trying to help.
I suspect that you are adding the label as a subview programatically in your cellForRowAtIndexPath method. You need to make sure that you are not adding that subview every time the cell is recycled. Instead create the label only when creating a new cell (not when recycling a cell) then assign a tag value to the label and then in the future, when it gets recycled, retrieve the label by tag value and change its text.
You are correct in that the cells are being reused. Your code should be set up roughly using the following pattern:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString* identifier = #"someidentifier";
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if(!cell) {
// create the cell and add all subviews to it
} else {
// update the cell and access appropriate subviews to modify what is displayed
}
return cell;
}
The cell will be created the first time the identifier is used. For all subsequent requests, the cell is pulled from the UITableView cache (via dequeueReusableCellWithIdentifier), and you can then access its subviews either by tag, index, type, or whatever mechanism you choose.
Somewhat related is that you can have multiple cell identifiers, which allows you to create multiple instances of different cells depending on the data that you have. In one of my projects, I have 4 different cells, each dependent upon the number of lines of data that they will display (anywhere between 1 and 4). This helps ensure a smooth scrolling experience regardless of how many lines the cell has since the renderer doesn't have to worry about dynamically changing the height of the cell on the fly.
Try this..
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
for (UIView* subView in cell.contentView.subviews)
{
[subView removeFromSuperview];
}
// Your Code to customize cell goes here.
}

Data not display UITableView?

In my application I parsed the data through NSXMLParser and made separate class to store that data from which i usually display the data. Everything works fine in simulator except the the title which is display in table cell with image. Images appears properly but the title not appear properly.
This is my code:-
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"TableCell3" owner:self options:NULL];
cell = nibLoadedCell;
}
NewsInfo *aNewsInfo = [appDelegate.newsArray objectAtIndex:indexPath.row];
titleLabel.text = aNewsInfo.title;
imageLabel.image = aNewsInfo.smallImageData;
return cell;
}
and in this way i configured my TableCell3.xib
Now i want my title data in 2 rows in label of the TableCell3.
I already used both the way through xib attributes settings or through code.
Code which i used instead of this xib attributes settings are:-
titleLabel.lineBreakMode = UILineBreakModeWordWrap;
titleLabel.numberOfLines = 2;
titleLabel.text = aNewsInfo.title;
Now Can any one help me to figure out this prob i want to display my title in two rows of the table view cell.
Thanks in Advance.
Just increase the height of your label and give a try. If the height is too less to hold 2 lines, the label will truncate the contents to 1 line and end with the ellipsis.
Shouldn't you be accessing them by
cell.titleLabel.text = sometest;
cell.imageLabel.image = someImage;
and also ensure that the titleLabel and imageLabel are connected properly to the outlets. And pls check your naming for the variables. imageLabel is not a good choice if you want that to be an imageview.

All UITableCells rendered at once... why?

I'm extremely confused by the proper behavior of UITableView cell rendering. Here's the situation:
I have a list of 250 items that are loading into a table view, each with an image. To optimize the image download, I followed along with Apple's LazyTableImages sample code... pretty much following it exactly. Really good system... for reference, here's the cell renderer within the Apple sample code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// customize the appearance of table view cells
//
static NSString *CellIdentifier = #"LazyTableCell";
static NSString *PlaceholderCellIdentifier = #"PlaceholderCell";
// add a placeholder cell while waiting on table data
int nodeCount = [self.entries count];
if (nodeCount == 0 && indexPath.row == 0)
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:PlaceholderCellIdentifier] autorelease];
cell.detailTextLabel.textAlignment = UITextAlignmentCenter;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
cell.detailTextLabel.text = #"Loading…";
return cell;
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellIdentifier] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
// Leave cells empty if there's no data yet
if (nodeCount > 0)
{
// Set up the cell...
AppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
cell.textLabel.text = appRecord.appName;
cell.detailTextLabel.text = appRecord.artist;
// Only load cached images; defer new downloads until scrolling ends
if (!appRecord.appIcon)
{
if (self.tableView.dragging == NO && self.tableView.decelerating == NO)
{
[self startIconDownload:appRecord forIndexPath:indexPath];
}
// if a download is deferred or in progress, return a placeholder image
cell.imageView.image = [UIImage imageNamed:#"Placeholder.png"];
}
else
{
cell.imageView.image = appRecord.appIcon;
}
}
return cell;
}
So – my implementation of Apple's LazyTableImages system has one crucial flaw: it starts all downloads for all images immediately. Now, if I remove this line:
//[self startIconDownload:appRecord forIndexPath:indexPath];
Then the system behaves exactly like you would expect: new images load as their placeholders scroll into view. However, the initial view cells do not automatically load their images without that prompt in the cell renderer. So, I have a problem: with the prompt in the cell renderer, all images load at once. Without the prompt, the initial view doesn't load. Now, this works fine in Apple sample code, which got me wondering what was going on with mine. It's almost like it was building all cells up front rather than just the 8 or so that would appear within the display. So, I got looking into it, and this is indeed the case... my table is building 250 unique cells! I didn't think the UITableView worked like this, I guess I thought it only built as many items as were needed to populate the table. Is this the case, or is it correct that it would build all 250 cells up front?
Also – related question: I've tried to compare my implementation against the Apple LazyTableImages sample, but have discovered that NSLog appears to be disabled within the Apple sample code (which makes direct behavior comparisons extremely difficult). Is that just a simple publish setting somewhere, or has Apple somehow locked down their samples so that you can't log output at runtime?
Thanks!
You certainly should not have an actual UITableViewCell instance for every row in the table. You should only see a few more instances than are visible in the UI. That is where your problem is. It doesn't have anything to do with the loading of images.
The only time I've seen a large number of cells instantiated when the cells where dequeued was when a coder had altered the frame of the tableview to make it much larger than the screen. The tableview retains enough cells from being dequeued to carpet its own frame regardless of what is visible. If the frame is to big then you get a lot of cells in queue.
NSLog does work in Apple examples so if you can't get NSLog output you've got something weird going on with the dev tools themselves.
You might want to shutdown Xcode and the simulator and restart and see if that clears up the odd behavior.
Oh my... mustISignUp is absolutely correct in saying "you definitely have a deeper underlying problem". I have variable-height table rows, and I was doing all height calculation and data storage on the rows themselves rather than on the data model that populated them. As a result, ALL cells were being created and populated by my heightForRowAtIndexPath method which was reading cell height from the cell objects. SO – lesson learned.
Thanks mustISignUp, and I love your username.
NSLog definitely isn't disabled within the Apple sample code. I don't know why you can't see it but you definitely have a deeper underlying problem.
Anyway, for your comparison:- if you have 6 rows on screen -tableView: cellForRowAtIndexPath: is called 6 times with index [0, 0] - [0, 5].
So, is that what you are seeing? How many times is -cellForRowAtIndexPath being called?