Application crashing after an attempt to delete row from UITableView - ios

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.effectsTableView beginUpdates];
Effect *effectToBeDeleted =self.effectsArray[indexPath.row];
[self deleteEffectWithName:effectToBeDeleted.name];
[self.effectsTableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationTop];
[self.effectsArray removeObjectAtIndex:indexPath.row];
[self.effectsTableView endUpdates];
}
}
The above function should in theory delete the rows as they are slided and the delete button is pressed. However the row does not delete instead is visible even after the
[self.effectsTableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationTop];
is called. And after the user scrolls to the bottom of the UITableView, while loading the last row, the app obviously crashes with "*** -[__NSArrayM objectAtIndex:]: index 9 beyond bounds [0 .. 8]" error since one of the objects has been deleted from the array.
the cellForRowAtIndexPath is as follows:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (!self.effectsArray)
{
[self loadEffectsInArray];
}
static NSString *cellIdentifier = #"EffectsCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
Effect *effectCellEffect = [self.effectsArray objectAtIndex:indexPath.row];
NSString *effectCellText = effectCellEffect.name;
[cell.textLabel setText:effectCellText];
cell.textLabel.font = [UIFont systemFontOfSize:[UIFont labelFontSize]];
return cell;
}
Below is the entire .m file for better context:
#import "EffectsManagementTableViewController.h"
#import "Effect+Manage.h"
#import "VLOGAppDelegate.h"
#import "AddEffectViewController.h"
#import "EffectFilterProperty+Manage.h"
#import "Effect.h"
#interface EffectsManagementTableViewController ()
#property (strong, nonatomic) IBOutlet UITableView *effectsTableView;
#property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
#property (nonatomic, strong) NSMutableArray *effectsArray;
#property (nonatomic, strong) NSString *currSelectedRowTitle;
#end
#implementation EffectsManagementTableViewController
-(NSString *)currSelectedRowTitle
{
if(!_currSelectedRowTitle)
{
_currSelectedRowTitle = #"";
}
return _currSelectedRowTitle;
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
VLOGAppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
self.managedObjectContext = appDelegate.managedObjectContext;
self.effectsTableView.dataSource = self;
self.effectsTableView.delegate = self;
}
-(void)viewWillAppear:(BOOL)animated
{
[self loadEffectsInArray];
[self.effectsTableView reloadData];
[self.effectsTableView setNeedsDisplay];
[self.effectsTableView setNeedsLayout];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (!self.effectsArray)
{
[self loadEffectsInArray];
}
return [self.effectsArray count];
}
//4
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (!self.effectsArray)
{
[self loadEffectsInArray];
}
static NSString *cellIdentifier = #"EffectsCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
//6
Effect *effectCellEffect = [self.effectsArray objectAtIndex:indexPath.row];
NSString *effectCellText = effectCellEffect.name;
//7
[cell.textLabel setText:effectCellText];
//[cell.detailTextLabel setText:#"5 stars!"];
cell.textLabel.font = [UIFont systemFontOfSize:[UIFont labelFontSize]];
//cell.backgroundColor = [UIColor blackColor];
//cell.textLabel.textColor = [UIColor whiteColor];
//cell.detailTextLabel.textColor = [UIColor grayColor];
//cell.textLabel.highlightedTextColor = self.effectsTableView.tintColor;
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return YES if you want the specified item to be editable.
return YES;
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.effectsTableView beginUpdates];
Effect *effectToBeDeleted =self.effectsArray[indexPath.row];
[self deleteEffectWithName:effectToBeDeleted.name];
[self.effectsTableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationTop];
[self.effectsArray removeObjectAtIndex:indexPath.row];
//[self loadEffectsInArray];
[self.effectsTableView endUpdates];
//[self.effectsTableView reloadData];
//[self.effectsTableView setNeedsLayout];
//[self.effectsTableView setNeedsDisplay];
}
}
-(void)deleteEffectWithName:(NSString *)effectName
{
NSArray *efpForEffectToBeDeleted = [EffectFilterProperty getEffectFilterPropertiesForEffectName:effectName forImmediateEngagement:NO forManagedObjectContext:self.managedObjectContext];
Effect *effectToBeDeleted = [Effect getEffectWithName:effectName forManagedObjectContext:self.managedObjectContext];
for (int i = 0; i < efpForEffectToBeDeleted.count; i++)
{
EffectFilterProperty *currEFP = efpForEffectToBeDeleted[i];
currEFP.relatedEffect = nil;
currEFP.relatedFilterProperty = nil;
[self.managedObjectContext deleteObject:currEFP];
}
[self.managedObjectContext deleteObject:effectToBeDeleted];
NSError *err = nil;
[self.managedObjectContext save:&err];
if (err != nil) {
//Problem while saving
}
}
-(void)loadEffectsInArray
{
self.effectsArray = [[Effect getAllEffectsForManagedObjectContext:_managedObjectContext] mutableCopy];
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Effect *effectCellEffect = [self.effectsArray objectAtIndex:indexPath.row];
self.currSelectedRowTitle = effectCellEffect.name;
[self performSegueWithIdentifier:#"PushedByTableView" sender:self];
}
/*
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:<##"reuseIdentifier"#> forIndexPath:indexPath];
// Configure the cell...
return cell;
}
*/
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:#"PushedByTableView"])
{
AddEffectViewController *destinationViewController = segue.destinationViewController;
NSString *selectedRowText = self.currSelectedRowTitle;
destinationViewController.effectToManage = [Effect getEffectWithName:selectedRowText forManagedObjectContext:self.managedObjectContext];
}
}
#end
What am I doing wrong here?

where are you beginning your updates, please add
[self.effectsTableView beginUpdates];
before deleting your row and no need of reloading the table when you are writing the begin updates and end updates.
Please don't remove the object from array before deleting the row.

IT'S WORKING
At end of your commitEditingStyle method add this line this will help you
[TableViewForFirstView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

try this code to add beginUpdatesmethod before delete called
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.effectsTableView beginUpdates];
Effect *effectToBeDeleted =self.effectsArray[indexPath.row];
[self deleteEffectWithName:effectToBeDeleted.name];
[self.effectsTableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationTop];
[self.effectsArray removeObjectAtIndex:indexPath.row];
[self loadEffectsInArray];
[self.effectsTableView endUpdates];
}

Try this code:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
Effect *effectToBeDeleted =[self.effectsArray objectAtIndex:indexPath.row];
[self deleteEffectWithName:effectToBeDeleted.name];
[self.effectsArray removeObjectAtIndex:indexPath.row];
[self loadEffectsInArray];
[self.effectsTableView reloadData];
}

As this message, it's crash for reason out of bound, so try check the array index before assign:
Effect *effectToBeDeleted = self.effectsArray > indexPath.row ? self.effectsArray[indexPath.row] : nil;
And
if(self.effectsArray.count > indexpath.row)
[self.effectsArray removeObjectAtIndex:indexPath.row];
else
NSlog("out of bound");

Related

Tableview Rows delete ios

I used two(canEditRowAtIndexPath and commitEditingStyle ) methods for delete rows based on index, whenever I went to next view and coming back to the table view deleted rows are again appeared.
How can I delete the rows permanently in table view? it would be very helpful to me.
Seems like you just delete the data from UI, so you got the problem.
You must delete the data from your source and UI at the same time.
Just reference this code:
#interface ViewController ()
#property UITableView* tableView;
#property NSMutableArray* dataArray;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_dataArray = [[NSMutableArray alloc] init];
for (int i = 0; i<10; i++) {
[_dataArray addObject:[NSString stringWithFormat:#"Test%d",i]];
}
_tableView = [[UITableView alloc] initWithFrame:[UIScreen mainScreen].bounds];
_tableView.dataSource = self;
_tableView.delegate = self;
[self.view addSubview:_tableView];
_tableView.editing = true;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return _dataArray.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:#"MyTableCell"];
if (nil == cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MyTableCell"];
}
cell.textLabel.text = [_dataArray objectAtIndex:indexPath.row];
return cell;
}
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
return true;
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
if (editingStyle == UITableViewCellEditingStyleDelete) {
//Delete data from source
[_dataArray removeObjectAtIndex:indexPath.row];
//Delete row from UI
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
}
}
#end
Hope it can help you.
Use NSMutableArray as your UITableView's datasource.
In commitEditingStyle Delegate....
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[datasourceArray removeObjectAtIndex:indexPath.row];
}
}

Delete rows method in commitEditingStyle

I'd like to implement a "swipe to delete" option to a tableview. I added the "commitEditingStyle" method and it triggers the swipe and a red box with "delete" shows, but I can't work out what should be inside that method. Any help?
Here's the code:
#import "NotificationTableView.h"
#import "NotificationTableViewCell.h"
#interface NotificationTableView () <UITableViewDelegate, UITableViewDataSource>
#property (nonatomic, strong) NSMutableDictionary* heights;
#end
#implementation NotificationTableView
-(void)awakeFromNib{
UINib *nib = [UINib nibWithNibName:#"NotificationTableViewCell" bundle:nil];
[self registerNib:nib forCellReuseIdentifier:#"NotificationTableViewCell"];
[self registerNib:nib forCellReuseIdentifier:#"NotificationTableViewCellSize"];
self.dataSource = self;
self.delegate = self;
self.estimatedRowHeight = 86;
self.rowHeight =
// (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1) ? UITableViewAutomaticDimension :
86;
self.tableFooterView = [UIView new];
_heights = [NSMutableDictionary new];
}
-(void)setNotifications:(NSArray *)notifications{
_notifications = notifications;
[self reloadData];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
[self reloadData];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section
{
return self.notifications.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NotificationTableViewCell* cell = [self dequeueReusableCellWithIdentifier:#"NotificationTableViewCell"];
[cell configureCellWithNotification:self.notifications[indexPath.row]];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
Notification* not = self.notifications[indexPath.row];
[self.notificationDelegate notificationTapped:not];
}
#end
Do not call reloadData in addition to deleteRowsAtIndexPaths:. Just do one.
You first need to update the data model used by your data source. In this case you need to remove the corresponding row from the self.notifications array. This means that you need a mutable array.
You don't need the calls to beginUpdate/endUpdate since you are only making a single call to modify the table view.
Try this:
- (void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
//Get the notification here
Notification* not = self.notifications[indexPath.row];
//Remove item in array
[self.notifications removeObjectIdenticalTo:not];
// Also remove that row from the table view with an animation
[tableView deleteRowsAtIndexPaths:#[indexPath]
withRowAnimation:UITableViewRowAnimationFade];
}

I can't delete item from list Xcode

Hi I am trying out Xcode and I want to delete items from the list. I can get the delete button to show but once the delete button is clicked it wont delete. The delete code is at the end of the code. There is something missing in the deleting part of the code and I am not really sure what it is.
#import "ToDoListTableViewController.h"
#import "ToDoItem.h"
#import "AddToDoItemViewController.h"
#interface ToDoListTableViewController ()
#property NSMutableArray *toDoItems;
#end
#implementation ToDoListTableViewController
- (void)loadInitialData {
ToDoItem *item1 = [[ToDoItem alloc] init];
item1.itemName = #"Buy milk";
[self.toDoItems addObject:item1];
ToDoItem *item2 = [[ToDoItem alloc] init];
item2.itemName = #"Buy eggs";
[self.toDoItems addObject:item2];
ToDoItem *item3 = [[ToDoItem alloc] init];
item3.itemName = #"Read a book";
[self.toDoItems addObject:item3];
}
- (IBAction)unwindToList:(UIStoryboardSegue *)segue {
AddToDoItemViewController *source = [segue sourceViewController];
ToDoItem *item = source.toDoItem;
if (item != nil) {
[self.toDoItems addObject:item];
[self.tableView reloadData];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
self.toDoItems = [[NSMutableArray alloc] init];
[self loadInitialData];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (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 [self.toDoItems count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ListPrototypeCell" forIndexPath:indexPath];
// Configure the cell...
ToDoItem *toDoItem = [self.toDoItems objectAtIndex:indexPath.row];
cell.textLabel.text = toDoItem.itemName;
if (toDoItem.completed) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
In your tableView:(UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath method you only delete the cell. You also have to delete your actual data.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete data from array
[self.toDoItems removeObjectAtIndex:indexPath.row];
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
When deleteRowsAtIndexPaths gets called it refreshes the tableViews data, which then calls cellForRowAtIndexPath. Now that you didn't change the data, nothing will change in the tableView.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete data from array
[self.toDoItems removeObjectAtIndex:indexPath.row];
// Reload table -> it's OK
[tableView reloadData];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}

Remove customized rows from UITableView

I'm just practicing with UITableView.
Here is what I did so far.
made cells with xib.file from scratch.
Data is stored in P-list.
Using [ MutableCopy] and convert array into mutableArray
It looks little strange but I made the delegate connection using storyboard ,so there's no "self.tableView.delegate = self" line here.
Now the problem is I can delete the objects in the mutableArray but not on UI. The row I selected is remained on the table.
I know "- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath" delegation method works but something goes wrong.
Any Advice is appreciated! Thanks:)
![#import "ViewController.h"
#import "Model.h"
#import "SimpleTableCell.h"
#interface ViewController ()
{
NSMutableArray *_recipesMC;
NSMutableArray *_imagesMC;
Model *_model;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
\[super viewDidLoad\];
// Do any additional setup after loading the view, typically from a nib.
Model *model = \[\[Model alloc\] init\];
\[model getBack\];
NSArray *recipes = model.recipes;
NSArray *images = model.imagesArray;
_recipesMC = \[recipes mutableCopy\];
_imagesMC = \[images mutableCopy\];
}
- (void)didReceiveMemoryWarning
{
\[super didReceiveMemoryWarning\];
// Dispose of any resources that can be recreated.
}
# pragma mark delegat patern
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return \[_recipesMC count\];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"SimpleTableCell";
SimpleTableCell *cell = (SimpleTableCell *)\[tableView dequeueReusableCellWithIdentifier:cellIdentifier\];
if(cell == nil)
{
NSArray *nib = \[\[NSBundle mainBundle\] loadNibNamed:#"Empty" owner:self options:nil\];
cell = \[nib objectAtIndex:0\];
}
cell.nameLabel.text = \[_recipesMC objectAtIndex:indexPath.row\];
if (indexPath.row < \[_recipesMC count\] - 1)
{
UIImage *image = \[UIImage imageNamed:_imagesMC\[indexPath.row\]\];
cell.thumbnailImageView.image = image;
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 78;
}
# pragma mark delegate touch
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%li",(long)indexPath.row);
UIAlertView *alert = \[\[UIAlertView alloc\] initWithTitle:#"HEY" message:\[NSString stringWithFormat:#"%#",_recipesMC\[indexPath.row\]\] delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil\];
\[alert show\];
UITableViewCell *cell = \[tableView cellForRowAtIndexPath:indexPath\];
if (cell.accessoryType !=
UITableViewCellAccessoryNone) {
cell.accessoryType =
UITableViewCellAccessoryNone;
}
else
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
\[self performSegueWithIdentifier:#"CellSelectionSegue" sender:self\];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Clicked DELETE BUTTON at %i",indexPath.row);
\[_recipesMC removeObjectAtIndex:indexPath.row\];
\[_imagesMC removeObjectAtIndex:indexPath.row\];
\[self.tableView reloadData\];
NSLog(#"count = %i",\[_recipesMC count\]);
}
# pragma mark Segue
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSLog(#"Segue");
}
#end
I'm pretty sure your self.tableView is nil.
It's because even if you set self as datasource and delegate, your table will work, but here you seems to have create your UITableView *tableView but didn't link it through your interface (if you do it with the builder).
Or you can simply call tableView rather than self.tableView because the delegate protocole gives you the table.
Just do it and it will work. And then, you can try the solution of Szu.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Clicked DELETE BUTTON at %i",indexPath.row);
[_recipesMC removeObjectAtIndex:indexPath.row];
[_imagesMC removeObjectAtIndex:indexPath.row];
[tableView reloadData];
NSLog(#"count = %i",[_recipesMC count]);
}
Yo should call deleteRowsAtIndexPath:wothRowAnimation:
e.g. in my code:
if (editingStyle == UITableViewCellEditingStyleDelete) {
ElKeyValuePair *pair = [self.locationFavoritesKeyArr objectAtIndex:[indexPath row]];
[self.locationFavoritesKeyArr removeObjectAtIndex:[indexPath row]];
ELCarpark *carpark = [self.agglomeration carparkForUid:[pair.val1 intValue]];
[carpark removeFromFavoritesAgglomerationUid:self.agglomeration.uid];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
Adding this code to the method tableView:commitEditingStyle:forRowAtIndexPath should remove the row from the data source and the UI.
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[_recipesMC removeObjectAtIndex:indexPath.row];
[_imagesMC removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:indexPath withRowAnimation:YES];
}
Finally remove the reloadData instruction.

When I press the button, I want the content of the text field to be added- IOS TableView

i have updated my code,
everything seems good, but when i press the add button it does not add the table.
then i realized i have forgot to initialize array, then everything is ok
#import "RootViewController.h"
#import "Hello_WorldAppDelegate.h"
#implementation RootViewController
#synthesize tableView;
- (void)viewDidLoad {
// Add the following line if you want the list to be editable
// self.navigationItem.leftBarButtonItem = self.editButtonItem;
}
- (IBAction)addToTable:(id)sender{
/*
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Do you want to say hello?" message:#"More info..." delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Say Hello",nil];
[alert show];
[alert release];
*/
[myArray addObject:textField.text];
[self.tableView reloadData];
textField.text=#"";
/*
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
}
[cell setText:[textField text]];
[self.tableView reloadData];
*/
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return[myArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
}
[cell setText:[myArray objectAtIndex:indexPath.row]];
// Set up the cell
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic
}
// Override if you support editing the list
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
}
/*if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}*/
}
/*
Override if you support conditional editing of the list
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
Override if you support rearranging the list
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/
/*
Override if you support conditional rearranging of the list
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated {
}
- (void)viewDidDisappear:(BOOL)animated {
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
- (void)dealloc {
[textField release];
[addButton release];
[super dealloc];
}
- (void)viewDidUnload {
[textField release];
textField = nil;
[addButton release];
addButton = nil;
[super viewDidUnload];
}
#end
ok i have solved my issue
thanks to everyone
Actually the problem is with your method name.
- (IBAction)addToTable:(id)sender:(UITableView *)tableView
change it like this
- (IBAction)addToTable:(id)sender
SWIFT(3.0)
#IBAction func add(_ sender: Any) {
yourarrayname.append(yourtextfield.text!)
yourtableview.reloadData()
}
what you need, first use an array as a data source for a table then on click on the button you need to add the textField content into an array then reload the table.
so your button action look like
- (IBAction)addToTable:(id)sender
{
[dataSouceArray addObject:yourTextField.text];
[yourTable reloadData];
yourTextField.text=#"";
}
and tableViewDelegate look like
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [yourDataSourceArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
}
[cell setText:[yourDataSourceArray objectAtIndex:indexPath.row]];
// Set up the cell
return cell;
}

Resources