I am facing an issue to delete a row from a table view
I am using a custom button in a UITableviewCell
When I tap that button the application crashes
My Code is Below
- (void)viewDidLoad
{
[DatabaseFiles check_Create_DB];
FavviewArray = [DatabaseFiles getData];
FavviewArray = [FavviewArray valueForKey:#"Fav_Msg"];
[mytableview setDataSource:self];
[mytableview setDelegate:self];
}
-(void)viewWillAppear:(BOOL)animated
{
//============Custome Favourite Button================
UIImage *image = [UIImage imageNamed:#"FAv_On-iphone.png"];
UnFavbtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 28, 28)];
[UIButton buttonWithType:UIButtonTypeCustom];
[UnFavbtn setBackgroundImage:image forState:UIControlStateNormal];
UnFavbtn.backgroundColor = [UIColor clearColor];
//cell.accessoryView = button;
[UnFavbtn addTarget:self action:#selector(UnFavouriteClick) forControlEvents:UIControlEventTouchUpInside];
//==================================================
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
return [FavviewArray count];
}
- (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] autorelease];
// }
cell.textLabel.text = [FavviewArray objectAtIndex:indexPath.row];
cell.accessoryView =UnFavbtn;
//[self.mytableview reloadData];
return cell;
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
selectedrow = (indexPath.row);
NSLog(#"Selected Row====%d",lastindexpath.row);
}
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (self.editing)
{
return UITableViewCellEditingStyleDelete;
}
return UITableViewCellEditingStyleDelete;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
lastindexpath = indexPath;
[self UnFavouriteClick];
// [FavviewArray removeObjectAtIndex:lastindexpath.row];
// [mytableview deleteRowsAtIndexPaths:[NSArray arrayWithObject:lastindexpath] withRowAnimation:UITableViewRowAnimationFade];
//[DatabaseOperation DeleteData:[Arrayid objectAtIndex:lastIndexPath.row+1 ]];
//[mytableview reloadData];
}
}
- (void)tableView:(UITableView *)tableView
willDisplayCell:(UITableViewCell *)cell
forRowAtIndexPath:(NSIndexPath *)indexPath
{
cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"Button-iphone.png"]];
}
- (void)UnFavouriteClick
{
NSLog(#"Last Indexpath====%d",lastindexpath.row+1);
//[FavviewArray removeObject:selectedrow];
//[FavviewArray removeObjectAtIndex:lastindexpath.row];
[mytableview deleteRowsAtIndexPaths:[NSArray arrayWithObject:lastindexpath] withRowAnimation:UITableViewRowAnimationFade];
[DatabaseFiles DeleteData:[FavviewArray objectAtIndex:lastindexpath.row+1 ]];
[mytableview reloadData];
}
You should delete the object in your model first then call deleteRowsAtIndexPaths:withRowAnimation:
And you don't need to call -reloadData
-(void)unFavouriteRowAtIndexPath:(NSIndexPath *)indexPath
{
[DatabaseFiles DeleteData:[FavviewArray objectAtIndex:indexPath.row+1 ]];
[mytableview deleteRowsAtIndexPaths:#[indexPath]
withRowAnimation:UITableViewRowAnimationFade];
}
Related
Please guide me in passing data. My storyboard contains two tabbars. In first view I put two buttons by selector in navigationbar that add and remove objects from bookmark. It's not a problem until here. When I change my tabbar to show updated bookmark database in tableview I see duplicated object in rows. I used
- (void)viewWillAppear:(BOOL)animated
and
[tableview reloadData];
but still it shows duplicated object. this is my second class code to show updated data
#implementation BookmarkViewController
#synthesize data , tableData , tblView ;
- (void)viewDidLoad{
[super viewDidLoad];
}
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:YES];
sql = [[SQLiteManager alloc]initWithDatabaseNamed:#"datadic.db"];
bookmarkQuery = #"SELECT EN FROM table WHERE BOOKMARK IS 1";
res = [sql getRowsForQuery:bookmarkQuery];
tableData = [[NSMutableArray alloc]initWithArray:[res valueForKey:#"EN"]];
NSLog(#"%#" , tableData);
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
indexRow = [NSIndexPath indexPathForRow:indexPath.row inSection:0];
tblView = [[UITableView alloc]init];
static NSString *myIdentifier = #"CELL";
myCell = [tblView dequeueReusableCellWithIdentifier:myIdentifier];
if (myCell == nil) {
myCell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier: myIdentifier];
}
[tblView reloadData];
myCell.textLabel.textColor = [UIColor blueColor];
myCell.textLabel.text = [tableData objectAtIndex:indexPath.row];
return myCell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [tableData count];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
[tableData removeObjectAtIndex:indexPath.row];
[tblView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:YES];
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
#end
The problem is most likely that you are instantiating a spare copy of UITableView every time [cellForRowAtIndexPath] is called. You call both [reloadData] as well as [deleteRowsAtIndexPaths] on this copy, which doesn't do anything.
Try this revised code (I'm assuming BookmarkViewController is a subclass of UITableViewController):
#implementation BookmarkViewController
#synthesize data , tableData , tblView ;
- (void)viewDidLoad{
[super viewDidLoad];
}
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:YES];
sql = [[SQLiteManager alloc]initWithDatabaseNamed:#"datadic.db"];
bookmarkQuery = #"SELECT EN FROM table WHERE BOOKMARK IS 1";
res = [sql getRowsForQuery:bookmarkQuery];
tableData = [[NSMutableArray alloc]initWithArray:[res valueForKey:#"EN"]];
NSLog(#"%#" , tableData);
[tblView reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
indexRow = [NSIndexPath indexPathForRow:indexPath.row inSection:0];
static NSString *myIdentifier = #"CELL";
myCell = [tableView dequeueReusableCellWithIdentifier:myIdentifier];
if (myCell == nil) {
myCell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier: myIdentifier];
}
myCell.textLabel.textColor = [UIColor blueColor];
myCell.textLabel.text = [tableData objectAtIndex:indexPath.row];
return myCell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [tableData count];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
[tableData removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:YES];
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
#end
I'd like my cells to have not only the Delete button while editing but also others. So what is an actual way to do this? I've tried making own UIView object for editingAccessoryView property but the problem is being that the view appears only on direct edit (i.e. clicking Edit button in Navigation Bar) and completely ignores swipes across a cell. Also tableView:editActionsForRowAtIndexPath: method was given a try but didn't work, at least I didn't manage to figure out how to get what I want with its function. Thank you in advance!
You Try This Code
-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewRowAction *button = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Button 1" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
NSLog(#"Action to perform with Button 1");
}];
button.backgroundColor = [UIColor greenColor]; //arbitrary color
UITableViewRowAction *button2 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Button 2" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
NSLog(#"Action to perform with Button2!");
}];
button2.backgroundColor = [UIColor blueColor]; //arbitrary color
return #[button, button2]; //array with all the buttons you want. 1,2,3, etc...
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
// you need to implement this method too or nothing will work:
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES; //tableview must be editable or nothing will work...
}
You CanTry also this code
.H File
{
NSMutableArray *dataArray;
}
#property (weak, nonatomic) IBOutlet UITableView *atableView;
#property(nonatomic,strong) NSMutableArray *dataArray;
**`.M file`**
- (void)viewDidLoad
{
[super viewDidLoad];
self.dataArray = [[NSMutableArray alloc] initWithObjects:#"Saurabh Sharma",#"Deepesh Jain",#"Ashish Sharma",#"Chandan",#"kanhaiya",#"Suchitra Bohra",#"Neha",#"Ghanshyam",nil];
self.title = #"Move Rows";
UIBarButtonItem *editButton = [[UIBarButtonItem alloc] initWithTitle:#"Edit" style: UIBarButtonItemStyleBordered target:self action:#selector(editButton:)];
[self.navigationItem setRightBarButtonItem:editButton];
// Do any additional setup after loading the view from its nib.
}
-(void)editButton:(UIBarButtonItem *)button
{
{
if(self.editing)
{
[super setEditing:NO animated:NO];
[atableView setEditing:NO animated:NO];
[atableView reloadData];
[self.navigationItem.rightBarButtonItem setTitle:#"Edit"];
[self.navigationItem.rightBarButtonItem setStyle:UIBarButtonItemStylePlain];
}
else
{
[super setEditing:YES animated:YES];
[atableView setEditing:YES animated:YES];
[atableView reloadData];
[self.navigationItem.rightBarButtonItem setTitle:#"Done"];
[self.navigationItem.rightBarButtonItem setStyle:UIBarButtonItemStyleDone];
}
}
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [dataArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifair=#"cellIdentifair";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifair];
if(cell==nil)
{
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifair];
}
cell.textLabel.text = [self.dataArray objectAtIndex:indexPath.row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
#pragma delete row in table view
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionView *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
return 10; // This is the minimum inter item spacing, can be more
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleDelete;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return TRUE;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView beginUpdates];
[dataArray removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];
[tableView endUpdates];
NSLog(#"Methods called when row is deleted");
}
#pragma Move Table View Delegte
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
NSString *item = [self.dataArray objectAtIndex:fromIndexPath.row];
[self.dataArray removeObject:item];
[self.dataArray insertObject:item atIndex:toIndexPath.row];
}
Works in Swift as well.
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
var completionButton = UITableViewRowAction(style: .Normal,
title: "Complete",
handler: {(action, index) in
/* Completion Code */
println("Complete")})
completionButton.backgroundColor = .lightGrayColor()
return [completionButton]
}
Also for iOS 11 you should use
- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView leadingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath - for right swipe
and
- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath - for left swipe
For ex.:
- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath {
UIContextualAction* action = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleNormal title:#"Title" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
// Do something
completionHandler(YES);
}
UISwipeActionsConfiguration * actionsConfiguration = [UISwipeActionsConfiguration configurationWithActions:#[action]];
return actionsConfiguration;
}
- (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");
I'm fairly new to this and am stuck on a problem. I can't get the ability to edit a table view i've created...
I have a button on the top right corner of the app that says "Edit" and - (IBAction)editTable:(id)sender, I've tried numerous attempts to get to edit this list I've created...
#implementation XYZViewController
#synthesize animalNames;
- (void)viewDidLoad
{
[super viewDidLoad];
//create array called animal names
animalNames = [[NSArray alloc]initWithObjects:
#"Cow",
#"Dog",
#"Cat",
#"Dear",
#"Penguin",
#"Lion",
#"Leapord",
#"Eal",
#"Snake",
#"Moth",
#"Cheetah",
#"Turtle"
, nil];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.animalNames count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier = #"MainCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
cell.textLabel.text = [self.animalNames objectAtIndex:indexPath.row];
return cell;
}
- (IBAction)editTable:(id)sender
{
NSLog(#"Editing");
[super setEditing:TRUE];
[self.tableView setEditing:TRUE];
self.editing = YES;
}
#end
Using Xcode 5.
You need to implement following methods to support table view editing:
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleDelete;
}
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
return NO;
}
You should declare animalNames as NSMutableArray as you are going edit it. Then you need to override some delegate methods to perform edit in tableview.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{
NSString *sourceItem = _animalNames[sourceIndexPath.row];
[_animalNames removeObjectAtIndex:sourceIndexPath.row];
[_animalNames insertObject:sourceItem atIndex:destinationIndexPath.row];
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
if (editingStyle == UITableViewCellEditingStyleDelete){
[_animalNames removeObjectAtIndex:indexPath.row];
[_tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
You can stop editing in editTable method like
- (IBAction)editTable:(id)sender
UIBarButtonItem *button = (UIBarButtonItem *)sender;
if ([button.title isEqualToString:#"Edit"]) {
button.title = #"Done";
[self.tableView setEditing:TRUE];
} else {
button.title = #"Edit";
[self.tableView setEditing:NO];
}
}
Hope this will help you
To edit the table view you need to call
[self.tableView setEditing:YES animated:YES]; on the table which you are using then
You have to implement the delegate method
tableView:commitEditingStyle:forRowAtIndexPath:
method to enable the deleting of rows. In order to delete the rows you need to use
Then Do this..
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
//Remove the object at the index we need to delete
[YourTableArray removeObjectAtIndex:indexPath.row];
//Delete the rows at the Indexpath.
[YourTable deleteRowsAtIndexPaths:[[NSArray alloc]initWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationRight];
[reminder_table reloadData];
//Set the table to editing NO.
[YourTable setEditing:NO animated:YES];
}
Please find below link for your reference
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TableView_iPhone/ManageInsertDeleteRow/ManageInsertDeleteRow.html#//apple_ref/doc/uid/TP40007451-CH10-SW19
I have subclass of UITableViewCell. Here is my setup
I have used Autolayout. Now when user swipe on cell , I can see "Delete" button , but it overlaps my right side imageview. Cell contents are not shifting. Here is my code
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.recentItemsArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"ProductCell";
ProductCell *cell = (ProductCell*)[tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil)
{
NSArray *cellArray = [[NSBundle mainBundle] loadNibNamed:#"ProductCell" owner:self options:nil];
cell=[cellArray objectAtIndex:0];
tableView.separatorColor = [UIColor clearColor];
}
Product *product = [self.recentItemsArray objectAtIndex:indexPath.row];
cell.lblProductName.text = product.name;
cell.lblNoOfBids.text = [NSString stringWithFormat:#"%#",product.numberOfBids];
cell.lblBuyItNowPrice.text = [NSString stringWithFormat:#"%# %#",CURRENCY_TYPE,product.buyItNowPrice];
cell.lblTimeRemaining.text = product.timeRemaining;
cell.lblLatestBid.text = [NSString stringWithFormat:#"%# %#",CURRENCY_TYPE,product.currentBidPrice];
cell.lblUserName.text = product.sellerName;
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 110.0f;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
//add code here for when you hit delete
[CommonUtils showAlertWithTitle:#"Alert" andMessage:#"Do you want to delete this product?"];
}
}
I saw several question on Stackoverflow , but didn't get any solution.
Can any body tell me what I am doing wrong ? Any kind of help is highly appreciated. Thanks
Update::
I tried adding UIImageView programatically. still image views are not shifting
- (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];
UIImageView* imageView = [[UIImageView alloc]initWithFrame:CGRectMake(260, 0, 50, 60)];
imageView.backgroundColor = [UIColor yellowColor];
[cell.contentView addSubview:imageView];
UIImageView* imageView1 = [[UIImageView alloc]initWithFrame:CGRectMake(20.0, 0, 60, 60)];
imageView1.backgroundColor = [UIColor redColor];
[cell.contentView addSubview:imageView1];
}
//cell.textLabel.text = #"ABC";
// Configure the cell...
return cell;
}
It happend with me. Verify if some cell property have the same name from other property in the view where the UITableView is.