I have created a few labels on my tableview using custom UITableViewCell and interface builder. Now i am using some third party control called BEMLineGraph and i want to add it to my tableview cell using code. It also has a few delegates and data source methods. I am doing the following but the problem is that i get duplicate graphs and messed up data upon scrolling up and down.
ProductsTableViewCell.m
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.productGraph = [[BEMSimpleLineGraphView alloc] initWithFrame:self.graphContainter.frame];
//_myGraph.enableTouchReport = YES;
self.productGraph.tag = 100;
self.productGraph.animationGraphStyle = BEMLineAnimationNone;
//_myGraph.enablePopUpReport = YES;
self.productGraph.enableXAxisLabel = YES;
self.productGraph.colorTouchInputLine = [UIColor whiteColor];
self.productGraph.colorXaxisLabel = [UIColor darkGrayColor];
self.productGraph.colorTop = [UIColor clearColor];
self.productGraph.colorBottom = [UIColor clearColor];
self.productGraph.colorLine = [UIColor colorWithRed:255.0/255.0 green:255.0/102.0 blue:255.0/102.0 alpha:1];
self.productGraph.colorPoint = [UIColor lightGrayColor];
[self addSubview:self.productGraph];
}
return self;
}
TableViewController.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
ProductsTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell = [cell initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.productGraph.frame = CGRectMake(0, 0, cell.graphContainter.frame.size.width, cell.graphContainter.frame.size.height);
cell.productGraph.dataSource = self;
cell.productGraph.delegate = self;
//All the other stuff is set here and works well.
}
- (NSInteger)numberOfPointsInLineGraph:(BEMSimpleLineGraphView *)graph
{
if (graph.tag == 100)
{
return productDetail.count;
}
else
{
return numbers.count;
}
one thing wrong I can see your code:
if (cell == nil)
{
cell = [cell initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
it should be:
if (cell == nil)
{
cell = [[ProductsTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
but this won't fix the problem of duplicate graphs
As you have subclassed the cell anyways, why don't you keep the delegate and datasource of the productGraph in the cell itself
If you have registered the ProductsTableViewCell class with the UITableView, then dequeueReusableCellWithIdentifier: will create an object of that class for you, and call its initWithCoder: method (for cells defined in Interface Builder). Therefore, remove the call to your initWithStyle:reuseIdentifier: and do initialisation in the initWithCoder: method of ProductsTableViewCell instead.
Then, in your cellForRowAtIndexPath: do only that what is specific for that cell. What that is depends on the implementation of your Graph class, but it needs to make sure that the old graph is not visible anymore.
Related
I am trying to use Storyboards on this project. I cntrl drag from a static tableview cell to a new viewcontroller select push.
When I run the app and click the tableviewcell, which I dragged from in the previous step, nothing happens?
I am not sure if I have screwed things up by also putting in my tableviewcontroller class the following method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier1 = #"Cell1";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1];
}
[cell.textLabel setFont:[UIFont fontWithName:#"GothamRounded-Light" size:18]];
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.detailTextLabel.backgroundColor = [UIColor clearColor];
[cell.detailTextLabel setFont:[UIFont fontWithName:#"GothamRounded-Light" size:12]];
cell.contentView.backgroundColor = [UIColor statOffWhite];
if (indexPath.row == 0) {
cell.textLabel.text = #"Profile";
}
else if (indexPath.row == 1) {
cell.textLabel.text = #"Support";
}
else if (indexPath.row == 2) {
cell.textLabel.text = #"Share";
}
else if (indexPath.row == 3) {
cell.textLabel.text = #"About";
}
else if (indexPath.row == 4){
cell.textLabel.text = #"";
cell.frame = CGRectMake(0, 0, self.view.bounds.size.width, 200);
UIImageView *watermark = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"watermark.png"]];
watermark.frame = CGRectMake((cell.frame.size.width/2) - (watermark.image.size.width/2), 80, watermark.image.size.width, watermark.image.size.height );
[cell addSubview:watermark];
}
return cell;
}
// UPDATE ////////
I took out the cellForRowAt method and the storyboard thing worked. But since I have taken out that method how can I set my font on my cell to be a custom font that isn't in Xcode's selections? I have included the font in my project, which I use everywhere.
What happen with your implementation of cellForRowAtIndexPath: is that your are creating cells from scratch and overwriting the storyboard's cells (hence your segue not being triggered).
If you defined static cells in your storyboard, you should not dequeue and create cells yourself. If your class is a subclass of UITableViewCellController, you could call the implementation of super and use the returned cell.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
// Customize your cell here
}
Note however that doing so makes little sense : all the things you are doing in your cellForRowAtIndexPath: method could and should for simplicity sake be done in the storyboard.
If you really need to customize a static cell programmatically, the way to go is to define an outlet to this cell in your view controller and customize the cell in the appropriate method (viewDidLoad for example).
I've read a lot at stack about 'dequeueReusableCellWithIdentifier' problem, I tried several answers and I can't seem to fix it.
I'll appreciate if someone can find what is the problem in my code
PARTIAL CODE:
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 2;
}
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return 10;
}
- (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];
}
if (indexPath.section == 0) {
if (indexPath.row == 0) {
cell.textLabel.text = [arrayOfQuestion objectAtIndex:indexPath.section];
}
else if (indexPath.row == 1) {
question1 = [[UITextField alloc] initWithFrame: CGRectMake(20, 3, 280, 38) ];
question1.adjustsFontSizeToFitWidth = YES;
question1.textColor = [UIColor blackColor];
question1.font = [UIFont systemFontOfSize:17.0];
question1.backgroundColor = [UIColor blueColor];
question1.autocorrectionType = UITextAutocorrectionTypeNo; // no auto correction support
question1.autocapitalizationType = UITextAutocapitalizationTypeNone; // no auto capitalization support
question1.textAlignment = UITextAlignmentRight;
question1.keyboardType = UIKeyboardTypeDefault; // use the default type input method (entire keyboard)
question1.returnKeyType = UIReturnKeyDone;
question1.tag = 0;
// question1.delegate = self;
question1.clearButtonMode = UITextFieldViewModeUnlessEditing; // no clear 'x' button to the right
[question1 setEnabled: YES ];
[cell addSubview: question1 ];
}
}
else if (indexPath.section == 1) {
if (indexPath.row == 0) {
cell.textLabel.text = [arrayOfQuestion objectAtIndex:indexPath.section];
}
else if (indexPath.row == 1) {
question2 = [ [ UITextField alloc ] initWithFrame: CGRectMake(20, 3, 280, 38) ];
question2.adjustsFontSizeToFitWidth = YES;
question2.textColor = [UIColor blackColor];
question2.font = [UIFont systemFontOfSize:17.0];
question2.backgroundColor = [UIColor blueColor];
question2.autocorrectionType = UITextAutocorrectionTypeNo; // no auto correction support
question2.autocapitalizationType = UITextAutocapitalizationTypeNone; // no auto capitalization support
question2.textAlignment = UITextAlignmentRight;
question2.keyboardType = UIKeyboardTypeDefault; // use the default type input method (entire keyboard)
question2.returnKeyType = UIReturnKeyDone;
question2.tag = 1;
// listTitleTextField.delegate = self;
question2.clearButtonMode = UITextFieldViewModeUnlessEditing; // no clear 'x' button to the right
[question2 setEnabled: YES ];
[cell addSubview: question2 ];
}
}
................
return cell;
}
Remember dequeueReusableCellWithIdentifier reuses the same object over and over to draw your cells. It's more efficient than creating a new cell for an unknown number of rows in your table view. This means as you add UITextFields with [cell addSubview: ... ]; the next time you need that cell it will already have that subview added to it's view.
You're better off creating a subclass of UITableViewCell that has the UITextField already added and accessible as a property. Then you can have two cell identifiers: one that refers to the question which is a basic UITableViewCell and one that refers to the answer, which is your new subclass.
On top of that, I'd look at making your code more flexible by refactoring the way you're building your table cells. As it is it's not very scalable and I bet a nightmare trying to access the answers.
I am making a form within a grouped tableview. In this form I have UIswitches and textfields. But after scrolling down, the cells styles are changing.
Here is my cellForRowAtIndex
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
static NSString *MyIdentifier = #"GenericCell";
cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] ;
}
NSString *text = nil;
if(indexPath.section == CREDENTIALS_SECTION){
if (indexPath.row == 0) {
NSLog(#"tot hier login");
UITextField *login = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
login.adjustsFontSizeToFitWidth = YES;
login.placeholder = #"example#gmail.com";
login.keyboardType = UIKeyboardTypeEmailAddress;
login.returnKeyType = UIReturnKeyNext;
login.backgroundColor = [UIColor clearColor];
login.tag = 0;
login.delegate = self;
[login setEnabled: YES];
[cell addSubview:login];
}else if (indexPath.row == 1){
NSLog(#"tot hier pass");
UITextField *pass = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
pass.adjustsFontSizeToFitWidth = YES;
pass.placeholder = #"Required";
pass.keyboardType = UIKeyboardTypeDefault;
pass.returnKeyType = UIReturnKeyDone;
pass.secureTextEntry = YES;
pass.backgroundColor = [UIColor clearColor];
pass.tag = 0;
pass.delegate = self;
[cell addSubview:pass];
}
if (indexPath.row == 0) { // Email
text = #"Email";
}
else if(indexPath.row == 1) {
text = #"Password";
}
}else if(indexPath.section == METHODS_SECTION){
UISwitch *toggleSwitch = [[UISwitch alloc]initWithFrame:CGRectMake(220, 10, 100, 30)];
toggleSwitch.tag = indexPath.row;
[toggleSwitch addTarget:self action:#selector(toggleSwitched:) forControlEvents:UIControlEventValueChanged];
[cell addSubview:toggleSwitch];
if (indexPath.row == 0) { // Web
text = #"Web applicatie";
}
else if(indexPath.row == 1) { //Mobile
text = #"Mobiele applicatie";
}
else if(indexPath.row == 2) { //Mail
text = #"E-mail";
}
}else if(indexPath.section == PHONE_SECTION){
UITextField *phoneText = [[UITextField alloc] initWithFrame:CGRectMake(20, 10, 185, 30)];
phoneText.adjustsFontSizeToFitWidth = YES;
phoneText.font = [UIFont fontWithName:#"Arial-BoldMT" size:18];
phoneText.keyboardType = UIKeyboardTypeNumberPad;
phoneText.delegate = self;
phoneText.textColor = [UIColor blackColor];
phoneText.text = _person.phone;
[cell addSubview:phoneText];
}else if(indexPath.section == REMARK_SECTION){
UITextView *textView = [[UITextView alloc]initWithFrame:CGRectMake(20, 10, 280, 260)];
textView.text = _person.remark;
textView.delegate = self;
textView.font = [UIFont fontWithName:#"Arial" size:15.0];
textView.backgroundColor = [UIColor clearColor];
[cell addSubview:textView];
text = #"";
}else if(indexPath.section == BUTTON_SECTION){
cell.backgroundColor = [UIColor redColor];
text = #"test";
}
cell.textLabel.text = text;
return cell;
}
After some searching I found that more people are having this problem. And that the problem lays in this piece of code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
static NSString *MyIdentifier = #"GenericCell";
cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] ;
}
NSString *text = nil;
But I don't find a solution for it.
Hope anybody can help!
Kind regards!
Clarification
Oké so here you see a screenshot of my form. below I have a red cell (save button) when I scroll down other cells are getting a red background. And some cells, text property's are changing.
That is not gong to work. Aparently you did not yet fully understand how the re-use mechanism works.
What do you do?
First you fetch a cell to be re-used. If you get one -fine so far but the problem comes later. If you don't get one then you create a new one.
When you have created a new one, which is the case at start before the user begins scrolling, then you add some UIItems depending on section and row. I will explain why this is not actually a smart thing to do.
Then the user scrolls. Cells will dissappear from screen and then made available for re-use. Then you will fetch the cells for re-use. But it may well happen that those cells already have additional UI-Items on them because you have used them before in that way. In the following process you will add new UI Items regardless whether there are already additional UI-Items on that very cell.
What can you do:
Create your own custom table cell subclasses. One subclass for each set of additional ui items that you may need. That is probably the neatest way of doing it. For each subclass use a different re-use identifier (!!!)
This is what I would recommend!
However, there are alternatives:
You could still live with your concept but invent an individual type of re-use identfier for each type of cell that has some type of additional ui item on it. If so, then make sure that these UI items are only created and added as sub-views in the if (cell == nil) branch of your code. Only create them once and then re-use them. Cell reuse-IDs could be "email-display", "email-input" , "password-display", "password-input", "switch", ...
A variance of the solution above would be, to calculate row and section
into the reuse-identifier. Such as "cell-id-0.2" for section 0 and
row 2 - or so. But still you will have to make sure that you really
re-use the additional UI views and do not re-create them every time
when the cell is filled with data. Plus, the layout in your first section varies depending on whether you want to input password and e-mail or just display them. You will still have to deal with those variations.
If cell == nil - meaning if a cell is re-used - then first clean it from every UI item that you may have added before. You can do that by tagging your UIViews with - let's say 99 - (anything different from 0 should do) upon creation and when reusing enumerate over all subviews and remove those, which have the tag 99. Despite that you can stick with the code that you have already made.
The easiest fix is:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"GenericCell"] ;
//some more code
return cell;
}
This would remove the reusability from the tableview, but since it's a limited settings view, it can be ok. I would still advice taking 1 or 2 from Hermann Klecker's solutions.
If you also need to persist UIControl state then use
static NSString *MyIdentifier = [NSString stringWithFormat:#"GenericCell%d",indexPath.row];
It will always return your unique table row and you can use it as required.
Try to remove all subviews from cell before reusing it. Try the code :
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] ;
}
else
{
[cell.contentView.subviews makeObjectsPerformSelector:#selector(removeFromSuperview)];
}
Remove all subviews before adding the subviews on cell.
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIdentifier]autorelease];
}
else
{
//To remove the subview of cell.
for (UIView *vwSubviews in [cell.contentView subviews])
{
[vwSubviews removeFromSuperview];
}
}
It may solves your problem.
Actually you have some bad code here.
In the mehthod
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
Unless it is not in if (cell == nil), you should NOT initialize and use any
-(void)addSubview:(UIView*)view
Why?
The cells are views which are reused from tableview. So If you add some subview, next time while reusing the cell, it will be added more subviews on it. Simply they are overlapped and may cause MEMORY LEAK.
Do not forget that cells are reusable. So;
if I have the following code unless I do not set text somewhere else. It is expected to all cells has the text in their text labels "this is a text". Because they are reusable.
if (someChangingBool) {
cell.textLabel.text = #"this is a text";
}
So I need to have an else for that if which sets the text something else.
For more Information.
Here is my cellForRowAtIndexPath method. Using ARC in my project.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
static NSString* cellIdentifier = #"ActivityCell";
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
Activity* activityToShow = [self.allActivities objectAtIndex:indexPath.row];
//Cell and cell text attributes
cell.textLabel.text = [activityToShow name];
//Slowing down the list scroll, I guess...
LastWeekView* lastWeekView = [[LastWeekView alloc] initWithFrame:CGRectMake(10, 39, 120, 20)];
[lastWeekView setActivity:activityToShow];
lastWeekView.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview:lastWeekView];
return cell;
}
LastWeelView allocation is slowing down the scroll i guess. In the lastWeekView, I fetch relationships of an entity from CoreData, perform a calculation on those values and draw some colors inside its drawRect method.
Here is the drawRect of LastWeekView
- (void)drawRect:(CGRect)rect
{
NSArray* activityChain = self.activity.computeChain; //fetches its relationships data
for (id item in activityChain) {
if (marking == [NSNull null])
{
[notmarkedColor set];
}
else if([(NSNumber*)marking boolValue] == YES)
{
[doneColor set];
}
else if([(NSNumber*)marking boolValue] == NO)
{
[notdoneColor set];
}
rectToFill = CGRectMake(x, y, 10, 10);
CGContextFillEllipseInRect(context, rectToFill);
x = x + dx;
}
}
What can I do to smoothen the scroll of tableView? If I have to asynchronously add this lastWeekView to each cell's contentView, how can i do it? please help.
I'd suggest allocating LastWeekView in cell's allocation scope. Also - fetch all core data objects in viewDidLoad so that in cellForRowAtIndexPath: method would retrieve it from array and not from the store. It should look something like this:
- (void)viewDidLoad
...
_activities = [Activity fetchAllInContext:managedObjectContext];
...
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCell];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
LastWeekView* lastWeekView = [[LastWeekView alloc] initWithFrame:CGRectMake(10, 39, 120, 20)];
lastWeekView.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview:lastWeekView];
}
Activity *activityToShow = [_activities objectAtIndex:[indexPath row]];
LastWeekView *lastWeekView = (LastWeekView *)[[[cell contentView] subviews] lastObject];
[lastWeekView setActivity:activityToShow];
return cell;
}
Note that you may also subclass the UITableViewCell to replace contentView with your LastWeekView to quickly access the activity property.
I have been trying to figure this out for a bit. I create a custom cell in its own xib file. In my view controller I have setup a table view controller with sections. The data that is being pulled into the table View is based off a fetch request controller from some core data that I have. I set up the custom cell in the cellForRowAtIndexPath function. I am creating a label for each cell within this function and populating the label with some data from the managed object. Everything seems ok when I first run. However, when I try to scroll up and down and new cells are reused the data in the labels are placed in the wrong cells. I have seen and heard this has to do with the reuse of cells. However, have not seen much examples on correcting this issue. Below is some of the code I have in my cellForRowAtIndexPath function. Let me know if any other input may be needed. Thanks for any help.
-(UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:#"CustomCell"];
/* do this to get unique value per cell due to sections. */
NSInteger indexForCell = indexPath.section * 1000 + indexPath.row + 1;
NSManagedObject *managedObject = [fetchedResultsController objectAtIndexPath:indexPath];
NSString *lastSession = nil;
UILabel *lastSessionLabel = nil;
if(cell == nil) {
lastSession = [managedObject valueForKey:#"last_session"];
[self.tableView registerNib:[UINib nibWithNibName:#"CustomCell"
bundle:[NSBundle mainBundle]]
forCellReuseIdentifier:#"CustomCell"];
self.tableView.backgroundColor = [UIColor clearColor];
cell = [aTableView dequeueReusableCellWithIdentifier:#"CustomCell"];
lastSessionLabel = [[UILabel alloc]initWithFrame:CGRectMake(410,55, 89, 35)];
lastSessionLabel.textAlignment = UITextAlignmentLeft;
lastSessionLabel.tag = indexForCell;
lastSessionLabel.font = [UIFont systemFontOfSize:17];
lastSessionLabel.highlighted = NO;
lastSessionLabel.backgroundColor = [UIColor clearColor];
cell.contentView.tag = indexForCell;
[cell.contentView addSubview:lastSessionLabel];
} else {
lastSessionLabel = (UILabel *)[cell viewWithTag:indexForCell];
}
if (lastSession && lastSession.length) {
lastSessionLabel.text = lastSession;
}
cell.textLabel.text = [NSString stringWithFormat:#"%#%#%#%#", #"Dr. ",
[managedObject valueForKey:#"first_name"],
#" " ,
[managedObject valueForKey:#"last_name"]];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.editingAccessoryType = UITableViewCellAccessoryNone;
return cell;
}
** Revised Code **
Below are the changes to code: in viewDidLoad is the following:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView registerNib:[UINib nibWithNibName:#"CustomCell"
bundle:[NSBundle mainBundle]]
forCellReuseIdentifier:#"CustomCell"];
self.tableView.backgroundColor = [UIColor clearColor];
}
in -(UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath: (NSIndexPath *)indexPath {
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:#"CustomCell"];
NSInteger indexForCell = indexPath.section * 1000 + indexPath.row + 1;
NSLog(#"index for cell: %d",indexForCell);
NSManagedObject *managedObject = [fetchedResultsController objectAtIndexPath:indexPath];
NSString *lastSession = [managedObject valueForKey:#"last_session"];
UILabel *lastSessionLabel = nil;
if(cell == nil) {
NSLog(#"Cell is nil! %#", [managedObject valueForKey:#"first_name"]);
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"CustomCell"];
self.tableView.backgroundColor = [UIColor clearColor];
}
lastSessionLabel = [[UILabel alloc]initWithFrame:CGRectMake(410,55, 89, 35)];
lastSessionLabel.textAlignment = UITextAlignmentLeft;
lastSessionLabel.tag = indexForCell;
lastSessionLabel.font = [UIFont systemFontOfSize:17];
lastSessionLabel.highlighted = NO;
lastSessionLabel.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview:lastSessionLabel];
/* Appropriate verbiage for nil last session. */
if (lastSession && lastSession.length) {
lastSessionLabel.text = lastSession;
}
return cell;
}
I am still having issues again with the label cell text changing when I scroll for different cells. I read some where about maybe having to use the prepareForReuse function for this.
You are only fetching lastSession when you create a new cell. Try putting this line before the if(cell == nil) statement.
lastSession = [managedObject valueForKey:#"last_session"];
I.e. this:
NSString *lastSession = [managedObject valueForKey:#"last_session"];
in stead of this:
NSString *lastSession = nil;
UPDATE
You are also setting the same tag for two views:
lastSessionLabel.tag = indexForCell;
...
cell.contentView.tag = indexForCell;
Based on your code sample you should only use the first line, i.e. set the tag for the lastSessionLabel
SECOND UPDATE
You should also only call registerNib: once in your view lifecycle, e.g. in viewDidLoad, not every time you need a new cell. Furthermore, you should create a new cell if cell == nil in stead of using dequeueReusableCellWithIdentifier:. E.g.
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"CustomCell"];