UITableView creates first row to last - iphone

I tried to make simple UIPopover with grouped table view. Everything is fine but first row is empty and it's data is in the last row. Whats wrong with my code?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = nil;
NSUInteger row = [indexPath row];
NSUInteger section = [indexPath section];
static NSString *kCellTextField_ID = #"CellTextField_ID";
cell = [tableView dequeueReusableCellWithIdentifier:kCellTextField_ID];
if (cell == nil) {
// a new cell needs to be created
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:kCellTextField_ID] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
} else {
// a cell is being recycled, remove the old edit field (if it contains one of our tagged edit fields)
UIView *viewToCheck = nil;
viewToCheck = [cell.contentView viewWithTag:kViewTag];
if (viewToCheck) [viewToCheck removeFromSuperview];
}
if (section == 1 && row == 0) {
UITextView *textView = [[self.sisalto objectAtIndex: row] valueForKey:kViewKey];
[cell.contentView addSubview:textView];
} else {
UITextField *textField = [[self.sisalto objectAtIndex: row] valueForKey:kViewKey];
[cell.contentView addSubview:textField];
}
return cell;
}

I might have found the problem. Look at the following code.
if (section == 1 && row == 0) {
UITextView *textView = [[self.sisalto objectAtIndex: row] valueForKey:kViewKey];
[cell.contentView addSubview:textView];
}
section == 1 indicates that you have two sections and your setting the first item of the second section to the first item of the array. That might be why it shows up last in your table view.

I finally figured out what was the problem. It was this sentence:
if (section == 1 && row == 0){
UITextView *textView = [[self.sisalto objectAtIndex: row] valueForKey:kViewKey];
[cell.contentView addSubview:textView];
}
It set just created cell with first value in datasource (sisalto). Obliviously, it should set first value of section 2 in datasource. When this is corrected everything works just fine.

Related

reloadData is only refreshing one row

I have a grouped tableView of 4 rows. I did a pretty big overhaul on how I am doing things between two views and now reloadData is acting weird. It will only refresh the data in one row. (the last one) and none of the others.
I have checked my values in my viewDidAppear method (where I call reloadData) and all my values are updated.
The code..
- (void)viewDidAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// reload the table data
[self.tableView reloadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Set up the cell...
static NSString *CellWithIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellWithIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellWithIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.text = [_tableGroup.options objectAtIndex:rowcount];
cell.tag = rowcount;
rowcount++;
//label for currently selected/saved setting
_currentSetting = [[BaseLabel alloc] initWithFrame:CGRectMake(160, 8, 115, 25)];
[_currentSetting setFont:[UIFont systemFontOfSize:14]];
_currentSetting.backgroundColor = [UIColor clearColor];
_currentSetting.textColor = [UIColor blueColor];
_currentSetting.textAlignment = NSTextAlignmentRight;
}
if (cell.tag == 0) {
_currentSetting.text = [NSString stringWithFormat:#"%# mi",[settings.val1 stringValue]];
}
else if(cell.tag == 1)
{
_currentSetting.text = [NSString stringWithFormat:#"%# items",[settings.val2 stringValue]];
}
else if(cell.tag == 2)
{
_currentSetting.text = [NSString stringWithFormat:#"%# items",[settings.val3 stringValue]];
}
[cell.contentView addSubview:_currentSetting];
return cell;
}
I've gone through with NSLog and everything is getting called as it should on reloadData, but the cells aren't changing their labels. Why?
The major problem I can see here is this :
cell.tag = rowcount;
rowcount++;
cell.tag must not be present inside if (cell == nil), you should rather take it out. Instead you shouldn't be checking cell.tag to set currentSettingText at all, you should be using indexPath.row
Also in each viewDidAppear,when you reload The Table, cellForRowAtIndexPath is called, which is incrementing rowCount and hence cell.tag everytime, where are you resetting it?
Problem 1: cellForRowAtIndexPath needs to return a cell, either by getting an existing cell, or by creating one and adding a subview (only when it creates a cell). When we have an existing cell, we can assume it has the subview added, so we just go looking for it. So it will work like this...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellWithIdentifier = #"Cell";
BaseLabel *_currentSetting;
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellWithIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellWithIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// new cell, so add a label
_currentSetting = [[BaseLabel alloc] initWithFrame:CGRectMake(160, 8, 115, 25)];
[_currentSetting setFont:[UIFont systemFontOfSize:14]];
_currentSetting.backgroundColor = [UIColor clearColor];
_currentSetting.textColor = [UIColor blueColor];
_currentSetting.textAlignment = NSTextAlignmentRight;
_currentSetting.tag = 128;
[cell.contentView addSubview:_currentSetting];
} else {
// existing cell so find the label
_currentSetting = (BaseLabel *)[cell viewWithTag:128];
}
Problem 2: Now we have a cell ready to go and a handle to a label subview, how should it be configured? The only sensible way is to look into our model based on the indexPath.
Here's where I can't help much without understanding the model, but the generic idea is this:
// say my model is an array of N arrays, one for each section, I would do this
NSArray *sectionModel = [self.mainModel objectAtIndex:indexPath.section];
id *modelElement = [sectionModel objectAtIndex:indexPath.row];
// now configure the cell based on modelElement
_currentSetting.text = [modelElement someStringAttributeOfMyModel];
return cell;
}
I can overlook the viewWillAppear call in viewDidAppear which is very strange but what is interesting is that you don't use the indexPath parameter in you method at all.
Since this parameter is the only way how to check which cell you are generating, you can get practically any result and the cells can be ordered randomly. A reloadData will just shuffle them again.
As the rowcount only increases, very soon none of your cell.tag == comparisons will evaluate to true.
By the way, the code is adding subviews to already existing cells - that means that after several reloads or some scrolling your cells will have many labels. Why you save the last label added to a cell into an instance variable, change it text and then move it to a different cell... that's a mystery.
Your code doesn't have any sense!

How do I insert a row at run time into an UITableView on iPhone?

I have created one button with action to add a row to the UITableView at run time but my code is not working. I can see the row animating down, but it's shown animated only on my UITableView row is not added. What can I do in this code to see the row added on cell?
I have 4 sections and I want to add row for 1 section on row 0 and 2 section on row 0:
-(IBAction)add:(id)sender
{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
NSArray* path = [NSArray arrayWithObject:indexPath];
// fill paths of insertion rows here
[self.mytableview beginUpdates];
[self.mytableview insertRowsAtIndexPaths:path withRowAnimation:UITableViewRowAnimationBottom];
[self.mytableview deleteRowsAtIndexPaths:path withRowAnimation:UITableViewRowAnimationBottom];
[self.mytableview endUpdates];
[self.mytableview reloadData];
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
NSInteger rows;
if (section==0) {
rows = 4;
//return rowForSectionOne;
//rows=rowForSectionOne++;
}
if (section == 1)
{
rows = 1;
}
return rows;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [mytableview dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
}
if ([indexPath row] == 0 && [indexPath section] == 0)
{
cell.textLabel.text=#"Title";
cell.accessoryView = textField;
titlename=textField.text;
[[cell imageView] setImage:[UIImage imageNamed:#"DetailViewDue.png"]];
NSLog(#"******:%#",titlename);
}
if ([indexPath row] == 1 && [indexPath section] == 0)
{
cell.textLabel.text=#"Tags";
cell.detailTextLabel.text=app.Tags;
[[cell imageView] setImage:[UIImage imageNamed:#"DetailViewTag.png"]];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
if ([indexPath row] == 2 && [indexPath section] == 0)
{
cell.textLabel.text=#"Notes";
cell.detailTextLabel.text=app.Notes;
[[cell imageView] setImage:[UIImage imageNamed:#"DetailViewNote.png"]];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"dd/MM/yyyy"];
fromDate = [[dateFormat stringFromDate:selectionData.fromDateSelected]retain];
if ([indexPath row] == 3 && [indexPath section] == 0)
{
cell.textLabel.text=#"DueDate";
cell.detailTextLabel.text=fromDate;
[[cell imageView] setImage:[UIImage imageNamed:#"DetailViewDue.png"]];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
if ([indexPath row] == 0 && [indexPath section] == 1)
{
cell.textLabel.text=#"Attach";
}
return cell;
}
Well you are doing it right. Lets say when the button is pressed -(IBAction)add:(id)sender is invoked. then compose indexPath with the proper row & section. Here section is 0,1,2,3 (since you have 4 sections -
NSIndexPath *indexPath0 = [NSIndexPath indexPathForRow:0 inSection:0];
NSIndexPath *indexPath1 = [NSIndexPath indexPathForRow:0 inSection:1];
NSIndexPath *indexPath2 = [NSIndexPath indexPathForRow:0 inSection:2];
NSIndexPath *indexPath3 = [NSIndexPath indexPathForRow:0 inSection:3];
//put these indexpaths in a NSArray
[tableView insertRowsAtIndexPaths:array withRowAnimation:UITableViewRowAnimationNone];
This should update the table. No need to do reloadData on the table as you are only adding one row (& not changing the entire table). Also make sure the dataSource has this new added entry per section otherwise your app will crash
You only have to add few lines of code in "cellForRowAtIndexPath" method
if(cell ==nil)
{
cell =[[UITableViewAlloc alloc]initWithStyle.... ]
}
int theRow = indexPath.row;
if(indexPath.section == 1) theRow += 3;
if(indexPath.section == 2) theRow += 5;
if(indexPath.section == 3) theRow += 4;
if(indexPath.section == 4) theRow += 3;
//load the view in it
cell.textLable . text = [<your object> objectAtIndexPath.row];
return cell;
Here you can add rows as many as you want....

UITableView cell/data disappear

I have a segmented tableView that loads all the data in all the cells of all the sections.
There is a textField in each cell.
The tableview doesn't fit the iPad screen completely, and I can't access all the invisible cells in order to read/save data. And when I make changes in "textField", then scroll up, the scroll down, all the changes are gone.
I need to load all the cells, even invisible once, to be able to access them.
I am sorry, I just started working with tables a few days ago...
I think that this problem has something to do with reusable cells, but not sure how to resolve it.
Looking for your help, please.
initialization:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 400, 30)] ;
textField.enabled = NO;
cell.accessoryView = textField;
[textField release];
}
UITextField *textField = (UITextField*)cell.accessoryView;
if(indexPath.section == 0)
cell.textLabel.text = [idenInfo objectAtIndex:indexPath.row];
else if (indexPath.section == 1)
cell.textLabel.text = [prodInfo objectAtIndex:indexPath.row];
else if (indexPath.section == 2)
cell.textLabel.text = [visInfo objectAtIndex:indexPath.row];
if(indexPath.section == 0)
textField.text = [idenInfoRez objectAtIndex:indexPath.row];
else if (indexPath.section == 1)
textField.text = [prodInfoRez objectAtIndex:indexPath.row];
else if (indexPath.section == 2)
textField.text = [visInfoRez objectAtIndex:indexPath.row];
textField = nil;
return cell;
}
First of all : you don't have to load all the cells including the invisible ones. That's the whole point of the UITableView and MVC Pattern : separate your views from your data.
What you'll want to do is update your Data source (that is idenInfoRez, prodInfoRez and vizInfoRez in your case) when the user has changed a value inside a textField. So you'll have to set your UIViewController as the delegate of each textfield and update the values as the user types in.
[UIView beginAnimations:#"ShiftUp" context:nil];
[UIView setAnimationDuration:0.0001];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger section = [indexPath section];
static NSString *CellIdentifier = #"Cell";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
cell = objCustCell;
cell.selectionStyle = UITableViewCellSelectionStyleNone ;
}
if (section == 0) {
switch (indexPath.row) {
case 0:{
cell.lable.text = #"Date of Birth";
cell.field.placeholder = #"Birth Name";
break;
}
case 1:{
cell.lable.text = #"Enter Your Name";
cell.field.placeholder = #"Full Name";
break;
}
default:
break;
}
}
[UIView beginAnimations:#"ShiftUp" context:nil];
[UIView setAnimationDuration:0.0001];
// [UIView beginAnimations: #"ShiftUp" context:nil];
NSLog(#"Load cellfor raw at index ");
// Configure the cell.
return cell;
}
Note : UIView animation will not allow text field to move away data or any UIcontroller will remain same in its old state !!
Don't Commit animation otherwise it will not working !!
What you can do is this: in the Editing Changed event of each of the TextField store the value contain in the text field in an NSMutableArray whose number equal the number of cells. i.e.
-(IBAction) EditingChanged: (id) sender
{
UITextField *txt =(UITextField*)sender;
NSString* str =[[NSString alloc] initWithString: txt.text];
//get current text string
NSInteger path =[tableView indexPathForSelectedRow].row;
// get currently selected row, this could be a bit different depending on the number of sections
[yourMutableArray insertObject: str atIndex: path];
[str release]
}
You can then populate the TextField with the values from the NSMutableArray anytime the cells are recreated i.e.
(UITableViewCell *) tableView: (UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*) indexPath
{
...... // create the cells here and use viewTag to get the textFields
textField.text= [yourMutableArray objectAtIndex:indexPath.row];
//This may be a bit different depending on the number of sections.
}
Also, note that it might be advisable to initialize yourMutable array to the capacity of the number of cells.
I am sorry if the codes are not well formatted as this is my first post on stackoverflow - also there might be some typos in the code. Hope this helps someone.
every time we allocate the cell to different data,the data will not reloading the cell,every time the data override previous data, before allocate the cell to clear cell,
like as cell=nil
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell=nil;
//it clear data in the cell
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 400, 30)] ;
textField.enabled = NO;
cell.accessoryView = textField;
[textField release];
}
You're right, the problem is the cells will be reused. There are two solutions to the problem, the quick and dirty one would be to not use reusable cells:
Remove this:
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
And just leave this:
UITableViewCell * cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 400, 30)] ;
textField.enabled = NO;
cell.accessoryView = textField;
[textField release];
That should be ok, if you have only a small number of cells in your tableview (about fewer than 50).
The better solution would be to leave cell reuse on, and fill their textfields as they are requested. The approach differs from app to app, but you basically never should access the cells directly, and store the data of the cell somewhere else, e.g. an NSArray of NSStrings. You could then manipulate the NSArray. Your cellForRowAtIndexPath method would look something like this:
textField.text = [arrData objectAtIndex:indexPath.row];

UITableView didSelectRowAtIndexPath add additional checkmark at tap

When i select a player in 'didSelectRowAtIndexPath' and add a checkmark on the selected row it adds an additional checkmark.
If i tap row = 0 it adds a checkmark to row = 0 and row = 11. This means that two row's are marked by one tap. If i tap row = 1 it adds an extra checkmark to row = 10 so it adds checkmark 10 rows forward. It seems like it only add the checkmark as the player does not get into the actual player-list.
Any help would be very much appreciated.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSLog(#"indexPath: %i", indexPath.row);
// To many players selected
if (nrOfSelectedPlayers == 6) { //This is max players allowed
UIAlertView *alertPlayer = [[UIAlertView alloc] initWithTitle:#"VARNING"
message:#"Du kan maximalt spela \n med sex spelare!"
delegate:self
cancelButtonTitle:#"Tillbaka"
otherButtonTitles:nil];
[alertPlayer show];
[alertPlayer release];
nrOfSelectedPlayers--;
checkDeletePlayer = YES;
}
else {
// Handle the number of selected players to be able to delete player +6
if (checkDeletePlayer == YES) {
checkDeletePlayer = NO;
nrOfSelectedPlayers++;
}
if (cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[selectedPlayersArray addObject:cell.textLabel.text];
nrOfSelectedPlayers++;
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
selectedPlayer = cell.textLabel.text;
for (int oo = 0; oo < nrOfSelectedPlayers; oo++) {
if ([selectedPlayersArray objectAtIndex:oo] == cell.textLabel.text) {
[selectedPlayersArray removeObjectAtIndex:oo];
nrOfSelectedPlayers--;
}
}
//nrOfSelectedPlayers--;
}
}
}
I am using storyboards with Dynamic Prototype Cells to display a list of states I used some of the ideas above before I found this solution
Step 1
#interface StateViewController : UITableViewController
{
NSMutableArray *checkedIndexPaths;
}
Step 2
(void)viewDidLoad
{
[super viewDidLoad];
self.states = [[GAIGStateStore sharedInstance]allStates];
//Setup default array to keep track of the checkmarks
checkedIndexPaths = [NSMutableArray arrayWithCapacity:self.states.count];
for (int i = 0; i < self.states.count; i++) {
[checkedIndexPaths addObject:[NSNumber numberWithBool:NO]];
}
}
Step 3
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//This toggles the checkmark
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.accessoryType == UITableViewCellAccessoryNone)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
//This sets the array
[checkedIndexPaths replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:YES]];
} else
{
cell.accessoryType = UITableViewCellAccessoryNone;
//This sets the array
[checkedIndexPaths replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:NO]];
}
}
Step 4
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:stateCell forIndexPath:indexPath];
UILabel *stateLabel = (UILabel *)[cell viewWithTag:1000];
StateProvince *myState = [self.states objectAtIndex:indexPath.row];
stateLabel.text = myState.label;
//Now set the check marks
// Assume cell not checked;
[cell setAccessoryType:UITableViewCellAccessoryNone];
NSNumber *num = [checkedIndexPaths objectAtIndex:indexPath.row];
if (num == [NSNumber numberWithBool:YES]) {
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
}
return cell;
}
The problem you are facing is caused by cell reusing.
Basically, if your UITableView has, let say 50 cells to display, it creates only 10 and then reuse them as you scroll down / scroll up. So whatever changes you did to the cell at row 0, it will be re-displayed for the row 11 as TableView uses the same cell etc.
What you want to do is to keep track of which players have been selected independently from cell. You can achieve that easily by creating a collection, let say NSMutableArray or NSMutableDictionary, which will store BOOL values in NSNumber objects, eg.
NSMutableArray *players = [NSMutableArray arrayWithCapacity:50];
for (int i = 0; i < 50; i++) {
[players addObject:[NSNumber numberWithBool:NO]];
}
Then in didSelectRowAtIndexPath:(NSIndexPath *)indexPath you do instead of operating on cell, you will simply change the value of a corresponding NSNumber object.
Then in cellForRowAtIndexPath:(NSIndexPath *)indexPath you configure cell accessory by checking the corresponding entry in players collection.
Or if you are really, really stubborn you could replace (THIS IS NOT RECOMENDED) the following line from the cellForRowAtIndexPath:(NSIndexPath *)indexPath:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
with:
UITableViewCell *cell = nil;
For others coming here (like I did) to see why their table selects random cells, you have to add something like the following to your cellForRowAtIndexPath:
// Assume cell not checked;
[cell setAccessoryType:UITableViewCellAccessoryNone];
for (int i = 0; i < checkedIndexPaths.count; i++) {
NSUInteger num = [[checkedIndexPaths objectAtIndex:i] row];
if (num == indexPath.row) {
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
}
}
I keep a NSMutableArray called checkedIndexPaths so that I know which indexPaths are checked. Keeping such an array allows you to easily limit the number of cells a user can check. Here's an example of my didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
// uncheck if already checked
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
cell.accessoryType = UITableViewCellAccessoryNone;
[checkedIndexPaths removeObject:indexPath];
}
else {
// make sure no more than 3 are selected
if ([checkedIndexPaths count] < 3) {
// check row
cell.accessoryType = UITableViewCellAccessoryCheckmark;
// add it to our list of checked indexes
[checkedIndexPaths addObject:indexPath];
} else {
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Note"
message:#"You can only select 3 rows."
delegate:nil
cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}

iPhone Admob UITableView troubles

I am sure this is a simple fix, but I can't seem to find it. I have a table view that currently works just fine, set up as:
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [creedsList objectAtIndex:row];
cell.imageView.image = [UIImage imageNamed:[creedsImages objectAtIndex:row]];
return cell;
The Admob SDK says to add this line:
[cell.contentView addSubview:[AdMobView requestAdWithDelegate:self]];
But then it populates EVERY cell with ads. Any thoughts?
EDIT:
I am using this code to populate:
NSUInteger row = [indexPath row];
cell.textLabel.text = [creedsList objectAtIndex:row];
You want to do that on only the particular rows you want the ads to show up in.
So if you wanted to show up only on the first row, you could do something like
static int adTag = 999; // Used for identifying whether cell already contains ad
UIView * adView = [cell.contentView viewWithTag:adTag];
if(row == 0 && !adView)
{
adView = [AdMobView requestAdWithDelegate:self];
adView.tag = adTag;
[cell.contentView addSubview:adView];
}
else if(row != 0 && adView)
{
// Must remove since cells are reused.
[adView removeFromSuperview];
}