Deleting and adding rows in uitableview [closed] - objective-c

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
guys, I have tableview, which is loading from my nsarray, but after managing cells, it shows elements in incorrect places.
Generating cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSArray *currentArray = [comments objectAtIndex:indexPath.section];
NSDictionary *currentComment = (NSDictionary *)[currentArray objectAtIndex:indexPath.row];
static NSString *CellIdentifier = #"TitleCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
int commentLevel = [[currentComment objectForKey:#"level"] intValue];
NSString *commentText = [currentComment objectForKey:#"text"];
cell.textLabel.tag = 0xff ;
cell.textLabel.numberOfLines = 0;
cell.textLabel.font = [UIFont fontWithName:#"Verdana" size:17.0];
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.text = commentText;
cell.textLabel.backgroundColor = [UIColor clearColor];
if (commentLevel > 0 && cell.imageView.image == nil) {
cell.imageView.image = [UIImage imageNamed:#"06-arrow-northwest.png"];
}
if (commentLevel == 0 && [[openedSections objectAtIndex:indexPath.section] boolValue] == NO) {
if ([currentArray count] > 1) {
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
}
return cell;
}
Editing method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if ([[openedSections objectAtIndex:indexPath.section] boolValue] == NO) {
[openedSections replaceObjectAtIndex:indexPath.section withObject:[NSNumber numberWithInt:1]];
NSMutableArray *rows = [[NSMutableArray alloc] init];
int i = 1;
while (i < [[comments objectAtIndex:indexPath.section] count]) {
NSIndexPath *path = [NSIndexPath indexPathForRow:i inSection:indexPath.section];
[rows addObject:[path copy]];
[path release];
i = i + 1;
}
[tableView beginUpdates];
[tableView insertRowsAtIndexPaths:rows withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView endUpdates];
[rows release];
} else if (indexPath.row == 0) {
[openedSections replaceObjectAtIndex:indexPath.section withObject:[NSNumber numberWithInt:0]];
NSMutableArray *rows = [[NSMutableArray alloc] init];
int i = 1;
while (i < [[comments objectAtIndex:indexPath.section] count]) {
NSIndexPath *path = [NSIndexPath indexPathForRow:i inSection:indexPath.section];
[rows addObject:[path copy]];
[path release];
i = i + 1;
}
[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:rows withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView endUpdates];
[rows release];
}
}
Have you any ideas?

You need to update your NSArray whenever you modify the cells in your table, otherwise your data source and view will get out of sync.
So whenever you call:
[tableView insertRowsAtIndexPaths:rows withRowAnimation:UITableViewRowAnimationAutomatic];
You should put
for (NSIndexPath *indexPath in rows)
{
[self.myDataArray insertObject:myRowModel atIndex:indexPath.row];
}
As well so that your view and model stay in sync.
Obviously the above is pseudocode (you'd have to create an instance of whatever your model objects are), and your array will have to be an NSMutableArray or it will crash when you try to insert into it.

Related

UITableView Add button on new cell

Im trying to add a button into a new cell in a tableview, for example, I need a button under cell '1' if dim is not 0.
However I'm unable to do it. Please enlighten me.
- (void)viewDidLoad
{
[super viewDidLoad];
_displaynum = [NSArray arrayWithObjects:#"1",#"2",#"3", nil];
_displayID = [NSArray arrayWithObjects:#"ID = 1",#"ID = 2",#"ID = 3", nil];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [_displaynum count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *lightIdentifier = #"lightIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:lightIdentifier];
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:lightIdentifier];
}
UISwitch *switchLights = [[UISwitch alloc] initWithFrame:CGRectMake(1.0, 1.0, 20.0, 20.0)];
cell.textLabel.text = [_displayLights objectAtIndex:indexPath.row];
cell.detailTextLabel.text =[_displayLightsID objectAtIndex:indexPath.row];
cell.accessoryView = switchLights;
switchLights.on = NO;
int dim = 1;
if ((dim =! 0)) {
NSArray *insertIndexPaths = [NSArray arrayWithObjects:
[NSIndexPath indexPathForRow:1 inSection:0],
nil];
NSArray *deleteIndexPaths = [NSArray arrayWithObjects:
[NSIndexPath indexPathForRow:2 inSection:0],nil];
[tableView beginUpdates];
[tableView insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationRight];
[tableView deleteRowsAtIndexPaths:deleteIndexPaths withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
}
return cell;
}
}
First of all, cellForRowAtIndexPath: is not the right place to insert or delete rows the way you are doing.
cellForRowAtIndexPath: gets called every time a new cell is drawn by iOS. So, this is the place where you can modify your cells and simply return it.
That said, this is what you need to do:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *lightIdentifier = #"lightIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:lightIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:lightIdentifier];
}
int dim = 1;
if (dim != 0 && indexPath.row == 1) {
CGRect buttonRect = CGRectMake(210, 25, 65, 25);
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = buttonRect;
// set the button title here if it will always be the same
[button setTitle:#"Action" forState:UIControlStateNormal];
button.tag = 1;
[button addTarget:self action:#selector(myAction:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:button];
}
return cell;
}

Selected row changes when scrolling UITableView

currently my situation is my fist row is checked by default. but when i want to uncheck it, it need user to click twice to uncheck it. may i know where i done wrongly?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier = #"Report_SelectGroupTableViewCell";
Report_SelectGroupTableViewCell *cell = (Report_SelectGroupTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil){
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"Report_SelectGroupTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
cell.indexPath = indexPath;
cell.delegate = self;
}
// [myTableView selectRowAtIndexPath:0 animated:NO scrollPosition:UITableViewScrollPositionNone];
//[self tableView:myTableView didSelectRowAtIndexPath:0];
[cell setSelectionStyle:NO];
NSString *groupID = [[groupArray objectAtIndex:indexPath.row] objectForKey:#"group_id"];
if ([groupID isEqualToString:selectedGroup]){
NSMutableDictionary *dict = [groupArray objectAtIndex:indexPath.row];
BOOL isSelected = [[dict objectForKey:#"isSelected"] boolValue];
if (!isSelected) {
isSelected = !isSelected;
[dict setObject:[NSNumber numberWithBool:isSelected] forKey:#"isSelected"];
}
cell.userInteractionEnabled = NO;
}
cell.groupName.text = [[groupArray objectAtIndex:indexPath.row] objectForKey:#"group_name"];
NSMutableDictionary *typeDict = [groupArray objectAtIndex:indexPath.row];
cell.tickButton.selected = [[typeDict objectForKey:#"isSelected"] boolValue];
if (cell.tickButton.selected) {
[cell.tickButton.layer setBorderColor:[UIColor clearColor].CGColor];
if([cell.groupName.text isEqual:#"All Users"])
{
[cell.tickButton setImage:[UIImage imageNamed:#"tick_Icon_empty.png"] forState:UIControlStateNormal];
}
}
else{
[cell.tickButton.layer setBorderColor:[UIColor whiteColor].CGColor];
}
if([cell.groupName.text isEqual:#"All Users"])
{
[cell.tickButton setImage:[UIImage imageNamed:#"tick_Icon.png"] forState:UIControlStateNormal];
[cell.tickButton.layer setBorderColor:[UIColor clearColor].CGColor];
[typeDict setObject:#"1" forKey:#"isSelected"];
}
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Report_SelectGroupTableViewCell *cell = (Report_SelectGroupTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
NSMutableDictionary *dict = [groupArray objectAtIndex:indexPath.row];
BOOL isSelected = [[dict objectForKey:#"isSelected"] boolValue];
isSelected = !isSelected;
[dict setObject:[NSNumber numberWithBool:isSelected] forKey:#"isSelected"];
if (cell.tickButton.isSelected == YES)
{
[cell.tickButton setSelected:NO];
[cell.tickButton.layer setBorderColor:[UIColor whiteColor].CGColor];
if([cell.groupName.text isEqual:#"All Users"])
{
[cell.tickButton setImage:[UIImage imageNamed:#"tick_Icon_empty.png"] forState:UIControlStateNormal];
}
}
else if (cell.tickButton.isSelected == NO)
{
[cell.tickButton setSelected:YES];
[cell.tickButton.layer setBorderColor:[UIColor clearColor].CGColor];
}
}
You should remove
[myTableView selectRowAtIndexPath:0 animated:YES scrollPosition:
UITableViewScrollPositionNone];
and use this to select the first row (this should be called once outside this method or you want to set this row selected everytime each cell is render)
[myTableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:YES scrollPosition:UITableViewScrollPositionNone];
And I don't know why you called this in this method
[myTableView.delegate tableView:myTableView didSelectRowAtIndexPath:0];
but if you want to call it you should change to this too
[myTableView.delegate tableView:myTableView didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
ps. You should set the cell's selectionStyle correctly to see the cell is selected.
Update::
Try to replace all codes in the method with this
Report_SelectGroupTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Report_SelectGroupTableViewCell"];
if (!cell){
cell = [[[NSBundle mainBundle] loadNibNamed:#"Report_SelectGroupTableViewCell" owner:self options:nil] objectAtIndex:0];
}
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
[tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:YES scrollPosition:UITableViewScrollPositionNone];
return cell;
Please tell me if the first row is not selected and highlighted.

Check marks are unchecked when scroll the tableview

i am using tableview and display data. in the table view all checkMark items sent mail. but when scroll the table check marks are unchecked. i don't want un check when scroll the table. please help me. i am developing below code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CustomCellIdentifier = #"CustomCellIdentifier ";
CaptureCell *cell = (CaptureCell *)[tableView dequeueReusableCellWithIdentifier: CustomCellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CaptureCell"
owner:self options:nil];
for (id oneObject in nib) if ([oneObject isKindOfClass:[CaptureCell class]])
cell = (CaptureCell *)oneObject;
}
if ([[[dataArray objectAtIndex:indexPath.row] objectForKey:#"CaptureId"]isEqualToString:[dict objectForKey:[[dataArray objectAtIndex:indexPath.row] objectForKey:#"CaptureId"]]])
{
cell.confirmMail.image = [UIImage imageNamed:#"mailConfirm.png"];
}
NSString *input;
input = [[dataArray objectAtIndex:indexPath.row]objectForKey:#"amount"];
[input stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
//NSLog(#"after removing white spaces %#",input);
double price;
NSString *numberAsString = nil;
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
NSLocale *gbLocale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US"];
[numberFormatter setLocale:gbLocale];
[gbLocale release];
[numberFormatter setNumberStyle: NSNumberFormatterCurrencyStyle];
if ([[input stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]length]!=0)
{
NSLog(#"the input is***** %#",input);
price=[[input stringByReplacingOccurrencesOfString:#"$" withString:#""] doubleValue];
NSLog(#"the price is %f",price);
numberAsString = [numberFormatter stringFromNumber:[NSNumber numberWithDouble:price]];
NSLog(#"the numberAsString...... %#",numberAsString);
}
[numberFormatter release];
cell.eventNameLbl.text = [[dataArray objectAtIndex:indexPath.row]objectForKey:#"expenseType"];
cell.expenTypeLbl.text = [[dataArray objectAtIndex:indexPath.row]objectForKey:#"empName"];
cell.dataLbl.text = [[dataArray objectAtIndex:indexPath.row]objectForKey:#"Date"];
cell.amountLbl.text = numberAsString;
cell.billImage.image = [UIImage imageWithData:[[dataArray objectAtIndex:indexPath.row]objectForKey:#"image"]];
//[cell.textLabel setText:[NSString stringWithFormat:#"Row %d", indexPath.row]];
cell.selectionStyle=UITableViewCellSelectionStyleNone;
NSIndexPath* selection = [tableView indexPathForSelectedRow];
if (selection && selection.row == indexPath.row) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
// if([[[captureArray objectAtIndex:indexPath.row]objectForKey:#"eventName"]isEqualToString:[[selectedData objectAtIndex:indexPath.row]objectForKey:#"eventName"]])
// NSLog(#"Equal");
//[cell setEditing:YES animated:YES];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *selected = [dataArray objectAtIndex:indexPath.row];
if([tableView isEditing] == YES)
{
AppDelegate *sharedDelegate = [[UIApplication sharedApplication]delegate];
sharedDelegate.isEditCapture = YES;
sharedDelegate.findDate = YES;
NSString *imgDataStr = [[NSString alloc]initWithData:[[dataArray objectAtIndex:indexPath.row]objectForKey:#"image"] encoding:NSUTF8StringEncoding];
NSLog(#"imageStr%#",imgDataStr);
ExpensesCaptureViewController_iPhone *nextController = [[ExpensesCaptureViewController_iPhone alloc] initWithNibName:#"ExpensesCaptureViewController_iPhone" bundle:nil];
nextController.captureId = [[dataArray objectAtIndex:indexPath.row] objectForKey:#"CaptureId"];
[self.navigationController pushViewController:nextController animated:YES];
[imgDataStr release];
[nextController release];
if([selectedData count]>0)
{
[selectedData removeObject:selected];
}
}
else {
if ([[[dataArray objectAtIndex:indexPath.row] objectForKey:#"CaptureId"]isEqualToString:[dict objectForKey:[[dataArray objectAtIndex:indexPath.row] objectForKey:#"CaptureId"]]])
{
NSLog(#"sent items");
}
else {
if (cell.accessoryType == UITableViewCellAccessoryNone)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[selectedData addObject:selected];
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
[selectedData removeObject:selected];
}
}
}
NSLog(#"DataObjects %d %#",[selectedData count] ,[[dataArray objectAtIndex:indexPath.row] objectForKey:#"eventName"]);
//[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
}
The problem that you scroll your tableView when - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method is called and you set
NSIndexPath* selection = [tableView indexPathForSelectedRow];
if (selection && selection.row == indexPath.row) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
that means when you will scroll indexPath will be for the current row only so the checkmark at the current row will still checked but the all the other rows will enter the else condition and the checkmark will be removed.
To fix it you should make a do the following:
define the following property:
#property (nonatomic)BOOL isViewIsLoadedForTheFirstTime;
-(void)viewDidLoad
{
self.isViewIsLoadedForTheFirstTime = YES;
}
then replace these lines in the (cellForRow) method
if (selection && selection.row == indexPath.row) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
to the following lines:
if (self.isViewIsLoadedForTheFirstTime) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
self.isViewIsLoadedForTheFirstTime = NO;
}
This will make you set the check mark only when the view loaded for the first time the when you will scroll it won't change.
I hope that will help you

Objective-C, iOS SDK, NSMutableArray, add elements and save data

Basically, every time I enter something in my textfield and save it to the table, the previous entry will be replaced by the new one. How do I add elements in a mutable array and save the last entry? I tried
[tabledata addObject....
and in the entry
tabledata.lastObject objectAtIndex...
but that didn't work.
here is what I have:
-(void)viewDidLoad
{
[super viewDidLoad];
titlestring = [[NSUserDefaults standardUserDefaults] objectForKey:#"titlehomework" ];
detailsstring = [[NSUserDefaults standardUserDefaults] objectForKey:#"detailshomework"];
tabledata = [[NSMutableArray alloc] initWithObjects:titlestring, nil];
tablesubtitles = [[NSMutableArray alloc] initWithObjects:detailsstring, nil];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
return [tabledata count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
UITableViewCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:#"homeworkcell"];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"homeworkcell"];
}
cell.textLabel.text = [tabledata objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [tablesubtitles objectAtIndex:indexPath.row];
cell.textLabel.font = [UIFont systemFontOfSize:14.0];
cell.textLabel.backgroundColor = [ UIColor clearColor ];
cell.detailTextLabel.backgroundColor = [UIColor clearColor];
//-----------------------------------------START----------------------------Set image of cell----
cellImage = [UIImage imageNamed:#"checkboxblank.png"];
cell.imageView.image = cellImage;
//--------------------------------------------END---------------------------end set image of cell--
return cell;
}
Without seeing more code, the best I can do is suggest something like this
[tabledata addObject:newTitle];
[tablesubtitles addObject:newSubtitle];
[tableView reloadData];
This assumes both newTitle and newSubtitle are the NSStrings you wish to add and that tableView is the pointer to the UITableView.

Pushing data from one View to another

I have a table list of promotions held in an NSSet which I load into an array for the purpose of displaying the title/name on the cell. However I want to use the didselectrow method to push the selected promotion onto an individual promotion page. I've making promo.featuredArray = self.featuredArray however it doesn't seem to be passing the data. My code is as follows.
Promo list.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
Featured*featured = [self.featuredArray objectAtIndex:indexPath.row];
cell.textLabel.text = featured.details;
cell.textLabel.textColor = [UIColor whiteColor];
cell.detailTextLabel.text = self.place.name;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Promo * promo= [[Promo alloc] initWithNibName:#"Promo" bundle:nil];
//Featured*featured = [self.featuredArray objectAtIndex:indexPath.row];
promo.featuredArray = self.featuredArray;
[self.navigationController pushViewController:promo animated:YES];
[promo release];
//[featured release];
}
Promo.m
#synthesize featuredArray, featured = __featured;
- (void)viewDidLoad
{
self.clearImage = [UIImage imageNamed:#"fav_icon.png"];
self.clearImagePressed = [UIImage imageNamed:#"fav_icon_sel.png"];
Featured*featured = [self.featuredArray init];
self.name.text = [NSString stringWithFormat:#"%#", __featured.name];
self.time.text = [NSString stringWithFormat:#"%#", __featured.time];
// self.description.text = [NSString stringWithFormat:#"%#", __featured.description];
self.placeName.text = [NSString stringWithFormat:#"%#", __featured.Place];
[super viewDidLoad];
if([__featured.imageURL hasPrefix:#"http"])
{
[self getImageForPlace];
}
// else
// {
// [self refreshImage];
// }
//
self.title = #"Promotion";
UIColor *background = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"background_texture.png"]];
self.view.backgroundColor = background;
[background release];
[featured release];
}
It's probably this line:
Featured*featured = [self.featuredArray init];
This is wrong in many ways.
Making this a community wiki because I don't have time to write a full answer.