I have a Core Data application set up with a ListViewController, a DetailViewController and an EditingViewController, where most of the editing occurs. On the ListViewController, I have a graphic of a checkbox, and I can toggle two images by selecting the row in
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
Is it possible to edit the Core Data record from the ListViewController so that I can make my selection persistent? I cannot work out the syntax to select the record, edit, and save the value - which will simply toggle from true to false.
jon
Thanks for the prompt response! Additional information after Answer 1. Your assumption is correct. I am modeling this application on the CoreData Books sample. I am not using a button, but rather using two images to create a checked and unchecked checkbox. I added a boolean "check" to my entity, recreated the header file, and added the header file to my ListViewController. Here is a simplified version of the datamodel header file.
#interface Patient : NSManagedObject
{
}
#property (nonatomic, retain) NSString * location;
#property (nonatomic, retain) NSNumber * check;
#property (nonatomic, retain) NSString * lastName;
#end
And here is my modification of your code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
NSManagedObject *entityObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
if (![entityObject.check boolValue]) {
entityObject.check = [NSNumber numberWithBool:YES];
cell.imageView.image = [UIImage imageNamed:#"check.png"];
}
else {
entityObject.check= [NSNumber numberWithBool:NO];
cell.imageView.image = [UIImage imageNamed:#"uncheck.png"];
}
However, this gives me the error "Request for member 'check' in something not a structure or union". I verified that the new attribute is a boolean and that the header file is imported to the ListViewController. Any thoughts?
Lastly, does this code eliminate the need to save entityObject.check to the database? Thanks again.
It would be nice to get a few more details about what your app does before we can provide a more informed recommendation. I'll make a few assumptions anyway to see if it helps...
Firstly, when dealing with BOOL properties in Coredata, it is important to remember that they are actually saved as NSNumbers so keep that in mind when you need to test their values and make sure you are using the right methods.
Assuming the data in your ListViewController is being populated by CoreData and your data model defines an entity "Entity" with an attribute of type BOOL called "favourite", here's what you can try:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
NSManagedObject *entityObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
if (![entityObject.favourite boolValue]) {
entityObject.favourite = [NSNumber numberWithBool:YES];
[self.yourToggleButton setSelected:YES]; // this assumes your checkbox is a UIButton and you want its view to be updated to checked when your BOOL == YES
}
else {
entityObject.favourite = [NSNumber numberWithBool:NO];
[self.watchListButton setSelected:NO];
}
The above assumes you have a fetchedResultsController taking care of the data fetching from your CoreData database too. If not I strongly recommend you check out one the tutorials from Apple (CoreData Books and CoreData Recipes) to understand how they work as it will make your life much easier - NSFetchedResultsController make it pretty straight forward to keep your data syncronised between different views which is something you are going to have to consider specially because you are allowing different attributes to be edited in different view controllers.
I hope this helps but feel free to ask any additional questions if you need to.
Cheers,
Rog
I came up with a slightly different solution, but Rog's post definitely got me on the right track. I had some trouble with the boolean syntax, so I changed the entity attribute to a string and used "N" and "Y" instead. I also found that I needed to save the value to make it persistent. I appreciate the help.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Establish connections
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
Patient *patient = [self.fetchedResultsController objectAtIndexPath:indexPath];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
// Toggle images and check value with each row tap
if ([patient.check isEqualToString: #"N"] == YES) {
cell.imageView.image = [UIImage imageNamed:#"check.png"];
patient.check = #"Y";
}
else {
cell.imageView.image = [UIImage imageNamed:#"uncheck.png"];
patient.check = #"N";
}
// Save check value
NSError *error = nil;
if (![context save:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
}
Related
I have used ASIHTTPRequest framework in my project to handle all network related tasks.
I have custom cell with thumbnail which is coming from web server and there are around 500 images so I have to reuse the cell to handle it. Due reusing of cell when we scroll through tableview we can see images of previous cells which will be replaced by new image.
If network connection is low its worse since it takes lot of time to download the image..so for that time you can see wrong image for particular because reusing cell so I need to find way so that this image replacement shouldn't be visible to user.
I am using ASIDownalod SharedCache method.
EDIT
NSString *reuseIdentifier = #"offerCell";
BRZOfferCell *offerCell = (BRZOfferCell*)[tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (offerCell==nil) {
offerCell = [[[BRZOfferCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier celltype:kDealCellTypeDealsList] autorelease];
}
[offerCell setImage:[UIImage imageNamed:IMAGE_NO_IMAGE]];
//---get the letter in the current section---
//NSString *alphabet = [mDealsIndex objectAtIndex:[indexPath section]];
//---get all deals beginning with the letter---
NSString* lSectionIndex = [NSString stringWithFormat:#"%i",[indexPath section]];
NSMutableArray *deals = [mIndexedOffersDic objectForKey:lSectionIndex];
if ([deals count]>0) {
//---extract the relevant deal from the deals array object---
Offer* lOffer = [deals objectAtIndex:indexPath.row];
[offerCell setOffer:lOffer];
offerCell.accessoryView = UITableViewCellAccessoryNone;
if (mTableView.dragging == NO && mTableView.decelerating == NO)
{
//Function : format image url to _thumb#2x.png and Initiate Image request download
//and set cache policy
[mListViewHelper InitImageRequest: lOffer.PromoImage indexPath: indexPath];
}
}
return offerCell;
As you said UITableView reuses cells in order to perform well, so you need to clear the cell before reuse it, or it's going to display the wrong data.
You also should use asynchronous calls, and some delegation to update cells.
I would actually take it a level higher and use NSOperationQueue, that allows you to set the maximum number of concurrent downloads, and canceling requests when leaving page.
What you might want to do is to create Data helpers
#protocol BookDataHelperDelegate <NSObject>
#required
- (void) bookDataHelperDidLoadImage:(BookDataHelper *)dataHelper;
#end
#interface BookDataHelper
#property (nonatomic, retian) UIImage *bookCover;
#property (nonatomic, retain) Book *book;
#property (nonatomic, assign) NSObject<BookDataHelperDelegate> *delegate;
- (void) fetchImageAsynchronouslyFromWebWithDelegate:(NSObject<BookDataHelperDelegate> *)delegate;
#end
This would be how you reload data on your table
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
CustomCell *cell = [tableView
dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
if (cell == nil)
{
cell = [[[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:SimpleTableIdentifier] autorelease];
}
BookDataHelper *dataHelper = [myArray objectAtIndex:indexPath.row];
if (!dataHelper.bookCover)
{
[cell.imageView setImage:nil];
[dataHelper fetchImageAsynchronouslyFromWebWithDelegate:self];
}
else
{
[cell.imageView setImage:dataHelper.bookCover];
}
cell.bookTitleLabel.text = dataHelper.book.title;
return cell;
}
- (void)bookDataHelperDidLoadImage:(BookDataHelper *)datahelper
{
[tableView reloadDate];
// here you would either reload the table completely
// Or you could reload specific cells
}
In your tableview cell delegate, when you get a reused or new, cell, clear the image before returning it. Update with the proper ownloaded image in an asynchronous callback. You might want to make sure the images are saved or retained somewhere else though if you don't want your app to keep redownloading them.
in ASIHTTPRequest framework its work on both type Synchronize and ASynchronize so firat tell me which one u use for get image data & also tell me that u send whole 500 image request at time or send as per your cell is loaded
or if you send 500 images request at a time than this on is not right as per the cell requirement send the request fro that cell image other wise its not feasible.
I have used ASIDownloadCache methods to solve my problem. Actually there are 2 solutions for this problem
Setting your own cache path instead of using SharedCache but i didn't went for this becuase I was already using sharedCache and found another efficient method which will avoid me changing my current implementation
In this approach I have used 2 methods from ASIDownloadCache methods(surprisingly ASIHTTPREquest website didn't mention these methods in their brief info)
2.1 First method - (BOOL)isCachedDataCurrentForRequest:(ASIHTTPRequest *)request
to verify if this particular image url is already cached or not if yes use 2nd method
2.2 - (NSData *)cachedResponseDataForURL:(NSURL *)url to get the cached image so that we can set the image in cellForRowAtIndexPath itself and you will not see image replacing issue due reusability of cell.
Here is the code :
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *reuseIdentifier = #"offerCell";
BRZOfferCell *offerCell = (BRZOfferCell*)[tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (offerCell==nil) {
offerCell = [[[BRZOfferCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier celltype:kDealCellTypeDealsList] autorelease];
}
[offerCell setImage:[UIImage imageNamed:IMAGE_NO_IMAGE]];
//---get the letter in the current section---
//NSString *alphabet = [mDealsIndex objectAtIndex:[indexPath section]];
//---get all deals beginning with the letter---
NSString* lSectionIndex = [NSString stringWithFormat:#"%i",[indexPath section]];
NSMutableArray *deals = [mIndexedOffersDic objectForKey:lSectionIndex];
if ([deals count]>0) {
//---extract the relevant deal from the deals array object---
Offer* lOffer = [deals objectAtIndex:indexPath.row];
[offerCell setOffer:lOffer];
offerCell.accessoryView = UITableViewCellAccessoryNone;
if ([mListViewHelper isCached:lOffer.PromoImage]) { // Is image available in Cache ?
// Image is available use image fomr cache directly
[offerCell setImage:[UIImage imageWithData:[mListViewHelper cacheDataWithNSURL:lOffer.PromoImage]]];
}
else{
//Function : Initiate Image request download and set cache policy
if (mTableView.dragging == NO && mTableView.decelerating == NO)
[mListViewHelper InitImageRequest: lOffer.PromoImage indexPath: indexPath];
}
}
return offerCell;
}
I have a tableview with custom cells in my App and each cell contains two checkbox buttons.
The problem is, when a scrolling event is triggered (up or down) it's reloading the tableview. Therefore, the checkbox buttons become to initial state.
Please give me a solution.
Thanks you
You're going to have to maintain a list yourself to determine which cells should be checked or not. Remember that in tableView:cellForRowAtIndexPath:, a proper implementation will recycle cells so that you never have more than 10-15 cells instantiated. This can cause some funky results if you don't handle for it properly. When I've done a poor implementation, I've seen certain cell properties "carry over" from one cell to the next.
Anyway, here's what I'd recommend (based on what I think you're asking):
1. Create a class to back each UITableViewCell
2. Create a property in that class to determine which of the two checkboxes (or neither or both) should be checked.
3. In your ViewController/TableViewController, maintain an NSMutableArray/NSArray where 1 item in the array = 1 cell in the UITableView.
4. In your tableView:cellForRowAtIndexPath: method, get a reference to the appropriate item in your array.
5. Then, check that instance's properties and set the checkbox values appropriately.
Sample Code:
TableView.h
#interface TableView : UITableViewController
#property (strong, nonatomic) NSMutableArray *itemArray;
#end
TableView.m
#implementation TableView
#synthesize itemArray;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Assume you get a valid, custom UITableViewCell at this point (named "cell")
// Configure the cell...
NSObject *classItem = [[self itemArray] objectAtIndex:[indexPath row]];
[[cell checkBox1] setChecked:[classItem checkbox1Checked]];
[[cell checkBox2] setChecked:[classItem checkbox2Checked]];
return cell;
}
#end
You should set the state of the button in the datasource and load this state when creating the cell. I wrote a small Xcode project to demonstrate this.
Well you should not use the TableView as the datasource.
Every time the cell comes into view the UITableViewDataSource is asked for the UITableViewCell at as indexpath.
- (void) tableView:(UITableView *)tableView setImage:(UIImage *)image forCellAtIndexPath:(NSIndexPath *)indexPath
In the is method you should set the checkbox state as it is reflected in your dataSource.
When the checkbox is changed save it in the data source with the selected state.
Example:
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"CheckedTableViewCell";
CheckedTableViewCell *cell = (CheckedTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
[[NSBundle mainBundle] loadNibNamed:cellIdentifier owner:self options:nil];
cell = (CheckedTableViewCell *)self.nibCell;
self.nibCell = nil;
}
item *item = [self objectAtIndexPath:indexPath];
cell.titleLabel.text = item.title;
cell.switch.on = item.selected;
return cell;
}
You could save the state in NSUserDefaults right when you click it. Just add a target with #selector(changedOne: ) and add the void statement:
- (void)changedOne: (id)sender {
NSUserDefaults *df = [NSUserDefaults standardUserDefaults];
NSString *row = [NSString initWithFormat:#"toggleOneRow%i",indexPath.row];
if (sender.on) {
[df setBool:YES forKey:row];
}
else {
[df setBool:NO forKey:row];
}
}
Are you using cellForRowAtIndexPath. If yes, then instead of
static NSString CellIdentifier=#"CellIdentifier"
use
NSString *CellIdentifier=[NSString stringWithFormat=#"CellIdentifier%d",indexPath.row];
Other approach you can take is assign tags to checkboxbuttons and take one dictionary in appDelegate file and set value for checkbox tag.initially you may set is either checked or unchecked.and set the values in cellforrowatindexpath method. set the values of checkboxes as per appdelegate dictionary.and update the state in appdelegate dictionary when user selects or deselects the button.
I want to populate a TableView with data from a database and, when tap a cell, in didSelectRowAtIndexPath, sending selected ID to a new View.
I would like to view, in cell text, the description of the record and to put ID in a hidden field/property of the cell, but I could not find a way to do it.
I know I can get an ID from the data source (something like [my_data_source objectAtIndex:indexPath.row]; ) but I don't really like this way, I would prefer to have an ID assigned to a single cell.
Is there a way to do it?
Thanks in advance and greetings.
I'm guessing you've come from web development? I also found it difficult to do it this way, but its the best way. IT probably is possible - but its better if you get used to doing it like this, it really is.
Basically define an NSArray in the .h file (so the whole script can use it).
then in the init function:
// set the array
myArray = [NSArray arrayWithObjects:#"One",#"Two",#"Threee",nil];
[myArray retain];
then the table view delegate methods:
// set numebr of rows
- (CGFloat)tableView:(UITableView *)tableView numberOfRowsForSection:(NSUInteger)section {
return [myArray count];
}
// set the cell titleLabel value
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// set the cell - I can't remember the exact code then do:
cell.textLabel.text = [myArray objectAtIndex:[indexPath row]];
}
// similarly
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"%#",[myArray objectAtIndex:[indexPath row]];
}
(disclaimer: these are just off the top of my head, and I haven't checked the exact methods - they're probably wrong in some way - but the code inside the functions is what you want really.)
When you've started using this you'll see its so much better than "hiding" an id somewhere in a table. To get things from the database I would suggest adding it all to a dictionary, or an array or similar and doing it like that when you init the class, but if you really want to do it dynamically then pretend your "hidden" ids are just index's of an array. So id#1 is at index 1 in your array. :)
Allright here is a quick hack on a different approach. I always like to deal with objects that are self contained. Pack all the data that you want into a custom class (here called MyData) for the table view you initialise it with the minimal amout that you need there. id and text that you pulled from the database. You also implement a function that can load the rest of the data from the DB.
When the item gets selected you pass the instance of your object to the subview controller and fill its data from the database. You can trigger the filling in the main viewcontroller or the subviewcontroller, that does not matter.
The main point is to pack all the data that goes together into one object (basically a "model" you already have a view and controller) and then fill views by accessing that object. This keeps your interface the same all the way through your applications. And makes changes easier. For example if you find out that it is better to fill in all the data from the DB at the start of your program you can do that now without changing the other views.
#interface MyObject : NSObject
{
}
// Create a stump object that contains only the necessary info
+ (id) withName:(NSString)name id:(int)id;
// loads the rest of your data from the DB
- (void) fillFromDb;
#property (readwrite, retain) NSString name;
#property (readwrite, assign) int id;
// The data fields that you need
#end
// in tableview controller
#interface MyTableViewController ...
{
NSMutableArray _dbData;
}
#end
#implementation MyTableViewController
- (void) viewDidLoad {
// Load your data from DB
for (int i =0; i < dbCount; ++i)
{
MyObject* data = [MyObject withName:dbName[i] id:dbId[i];
[_dbData addObject:data];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
cell.textLabel.text = [_dbData objectAtIndex:[indexPath row]];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//Create Subviewcontroller
// Optional call fillFromDb here and not in subviewcontroller
subviewcontroller.dbData = [_dbData objectAtIndex:[indexPath row]];
//activate subview
}
#interface SubViewController {
MyObject* _dbData;
}
#end
#implementation SubViewController
- (void) viewDidLoad {
[_dbData fillFromDb];
// Do View Initialisations with the newly fetched Data
}
The code is here just to demonstrate the architecture
How are UITableView cells made to be able to be deleted by users?
A quick example would be:
// create a mutable array to manage your table data
NSMutableArray *tableList;
#property (nonatomic, retain) NSMutableArray *tableList;
in your viewDidLoad method you can initialize it with data (you should check if tableList is nil first though)
NSString *path = [[NSBundle mainBundle] pathForResource:#"TableData" ofType:#"plist"];
NSMutableArray *array = [[NSMutableArray alloc] initWithContentsOfFile:path];
self.tableList = array;
[array release];
then in the implementation file, you implement this delegate method
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger row = [indexPath row];
[self.tableList removeObjectAtIndex:row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
you can then toggle editing mode via
[self.tableView setEditing:!self.tableView.editing animated:YES];
Take a look at the table view data source delegate method -tableView:commitEditingStyle:forRowAtIndexPath:.
You override this method in your table view delegate (usually your table view controller) and put your deletion logic here.
For example, you can call a UIAlertView to ask the user to confirm the deletion, or just manipulate the data model directly, removing the object from your table view's data source.
I know this question has been asked before, and I took a look at the answer to this question. However, I'm still confused as to how to implement reordering with a UITableView in a Core Data project. What I know is that I need to have a "displayOrder" attribute in my Entity to track the order of items, and I need to enumerate through all the objects in the fetched results and set their displayOrder attribute.
In the given code in the question I linked to, the table view delegate method calls a method like this [self FF_fetchResults];, and the code for that method is not given so its hard to tell what exactly it is.
Is there any sample code that demonstrates this? That would be simpler to look at than sharing large chunks of code.
Thanks
I'm not sure which part you are having trouble with (based on the comments)... but here is my suggestion. The displayOrder is just a simple attribute on a NSManagedObject class. If you can save a managed object, then you will be able finish this feature. Lets first take a simple NSManagedObject:
#interface RowObj : NSManagedObject
{
}
#property (nonatomic, retain) NSString *rowDescription;
#property (nonatomic, retain) NSNumber *displayOrder;
Next, we need to have local copy of the data being displayed in the tableview. I have read through the comments you have made and I'm not really sure if you are using the FetchedResultsController or not. My suggestion would be to start simple and just use a normal tableviewcontroller where you update the row data whenever a user changes the display order... then save the order when the user is done editing.
The interface for this tableviewcontoller would look like this:
#interface MyTableViewController : UITableViewController {
NSMutableArray *myTableViewData;
}
#property(nonatomic,retain) NSMutableArray *myTableViewData;
#end
Next, we need to load the the table view data in the viewWillAppear method:
- (void)viewWillAppear:(BOOL)animated {
myTableViewData = [helper getRowObjects]; // insert method call here to get the data
self.navigationItem.leftBarButtonItem = [self editButtonItem];
}
There are 2 things going on here... (I'll explain the editButtonItem later) the first is that we need to get our data from CoreData. When I have to do this I have some sort of helper(call it what you want) object do the work. A typical find method would look like this:
- (NSMutableArray*) getRowObjects{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"RowObj" inManagedObjectContext:[self managedObjectContext]];
[request setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"displayOrder" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[sortDescriptor release];
NSError *error;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil) {
// Handle the error.
}
[request release];
return mutableFetchResults;
}
Now that you have your data, you can now wait for the user to edit the table. That is where the [self editButtonItem] comes into play. This is a built in feature that returns a bar button item that toggles its title and associated state between Edit and Done. When the user hits that button, it will invoke the setEditing:animated: method:
To update the display order you need to override the setEditing method on the UITableViewController class. It should look something like this:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
[myTableView setEditing:editing animated:animated];
if(!editing) {
int i = 0;
for(RowObj *row in myTableViewData) {
row.displayOrder = [NSNumber numberWithInt:i++];
}
[helper saveManagedObjectContext]; // basically calls [managedObjectContext save:&error];
}
}
We don't have to do anything when the user is in edit mode... we only want to save once they have pressed the "Done" button. When a user drags a row in your table you can update your display order by overriding the canMoveRowAtIndexPath and moveRowAtIndexPath methods:
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return true;
}
(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath {
RowObj *row = [myTableViewData objectAtIndex:sourceIndexPath.row];
[myTableViewData removeObjectAtIndex:sourceIndexPath.row];
[myTableViewData insertObject:row atIndex:destinationIndexPath.row];
}
Again, the reason I don't update the displayOrder value here is because the user is still in edit mode... we don't know if the user is done editing AND they could even cancel what they've done by not hitting the "Done" button.
EDIT
If you want to delete a row you need to override tableView:commitEditingStyle:forRowAtIndexPath and do something like this:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the managed object at the given index path.
RowObj *row = [myTableViewData objectAtIndex:indexPath.row];
[helper deleteRow:row];
// Update the array and table view.
[myTableViewData removeObjectAtIndex:indexPath.row];
[myTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
}
}