iOS

Delete a Row from UITableView and Model-View-Controller


As said in the previous post, I have another question to answer before moving onto Storyboard tutorial.

How can I delete a row from UITableView?

This is another common question people raised when building the Simple Table App. Again, it’s easier than you thought. But before jumping into the coding part, I have to introduce you the Model-View-Controller model, which is one of the most quoted design patterns for user interface programming.

You can’t escape from learning Model-View-Controller (MVC for short) if you’re serious about iOS programming. Not limited to iOS programming, MVC is commonly used and quoted in other programming languages such as Java. If you come from other programming backgrounds, MVC shouldn’t be new to you.

Delete Row Featured Image

Understanding Model-View-Controller

At the heart of MVC, and the idea that was the most influential to later frameworks, is what I call Separated Presentation. The idea behind Separated Presentation is to make a clear division between domain objects that model our perception of the real world, and presentation objects that are the GUI elements we see on the screen. Domain objects should be completely self contained and work without reference to the presentation, they should also be able to support multiple presentations, possibly simultaneously. This approach was also an important part of the Unix culture, and continues today allowing many applications to be manipulated through both a graphical and command-line interface.

By Martin Fowler

No matter what computer language you learn, one important concept that makes you become a better programmer is Separation of Concerns (SoC). The concept is pretty simple. Concerns are the different aspects of software functionality. The concept encourages developers to break a big feature or program into several areas of concern that each area has its own responsibility. The delegate pattern that is commonly found in iOS programming we explained in the earlier tutorial is one of the example of SoC.

Here, model-view-controller is another example of SoC. The core idea behind MVC is to clearly separate user interface into three areas (or groups of objects) that each area is responsible for a particular functionality. As the name suggests, MVC breaks an user interface into three parts:

Model – model is responsible for holding the data or any operations on the data. The model can be as simple as an array object that stores all the table data. Add, edit and delete are examples of the operations. In reality, the operations are usually known as business rules.

View – view manages the visual display of information. For example, UITableView shows information in a table view format.

Controller – controller is the bridge between model and view. It translates the user interaction from the view (e.g. tap) into appropriate action to be performed in the model. For example, user taps a delete button in the view and controller, in turn, triggers a delete operation in the model. After that, it also requests the view to refresh itself to reflect the update of the data model.

To better help you understand MVC, let’s use our Simple Table app as an example. The app displays a list of recipes in the table view. If you turn the concept into visual representation, here is how the table data is displayed:

MVC Model for Simple Table

MVC Model Illustrated Using Simple Table as Example

The recipe information that are stored in separate array objects is the Model. Each table row maps to an element of the recipe arrays. The UITableView object is the View that is the interface to be seen by the user. It’s responsible for all the visuals (e.g. color of the table rows, font size and type). The TableViewController acts as the bridge between the TableView and Recipe data model. When display table data, UITableView actually asks the Controller for the data to display, that in turn, picks the data from the model.

How To Delete a Row from UITableView

I hope you have a better understanding about Model-View-Controller. Now let’s move onto the coding part and see how we can delete a row from UITableView. To make thing simple, I’ll use the plain version of Simple Table app as an example.

If you thoroughly understand the MVC model, you probably have some ideas how to implement row deletion. There are three main things we need to do:

1. Write code to switch to edit mode for row deletion
2. Delete the corresponding table data from the model
3. Reload the table view in order to reflect the change of table data

1. Write code to switch to edit mode for row deletion

In iOS app, user normally swipes across a row to initiate the delete button. Recalled that we have adopted the UITableViewDataSource protocol, if you refer to the API doc, there is a method named tableView:commitEditingStyle:forRowAtIndexPath. When user swipes across a row, the table view will check to see if the method has been implemented. If the method is found, the table view will automatically show the “Delete” button.

Simply add the following code to your table view app and run your app:

Even the method is empty and doesn’t perform anything, you’ll see the “Delete” button when you swipe across a row.

Swipe to Delete Table Row

Swipe to Delete a Table Row

2. Delete the corresponding table data from the model

The next thing is to add code to the method and remove the actual table data. Like other table view methods, it passes the indexPath as parameter that tells you the row number for the deletion. So you can make use of this information and remove the corresponding element from the data array.

In the original code of Simple Table App, we use NSArray to store the table data (which is the model). The problem of NSArray is it’s non-editable. That is, you can’t add/remove its content once the array is initialized. Alternatively, we’ll change the NSArray to NSMutableArray, which adds insertion and deletion operations:

In the tableView:commitEditingStyle method, add the following code to remove the actual data from the array. Your method should look like this:

The NSMutableArray provides a number of operations for you to manipulate the content of an array. Here we utilize the “removeObjectAtIndex” method to remove a particular item from the array. You can try to run the app and delete a row. Oops! The app doesn’t work as expected.

It’s not a bug. The app does delete the item from the array. The reason why the deleted item still appears is the view hasn’t been refreshed to reflect the update of the data model.

3. Reload the table view

Therefore, once the underlying data is removed, we need to invoke “reloadData” method to request the table View to refresh. Here is the updated code:

Test Your App and Delete a Row

Try to run your app again and swipe to delete a row. You should be able to delete it.

Simple Table App - Row Deletion

Delete a Table Row in Simple Table App

As always, leave me comment to share your experience about the tutorial.

Update: You can now download the source code of the Xcode project.

iOS
Introduction to ReplayKit: Building a Simple Screen Recording App
iOS
How To Add Search Bar in Table View
iOS
How to Use Xcode Instrument to Optimize Your Swift Code
  • June

    JuneJune

    Author Reply

    Not really understand this 1…
    where shud i add those codes in?


    • Simon Ng

      Simon NgSimon Ng

      Author Reply

      This is a follow-up for the Simple Table app. So you can add the code in SimpleTableViewController.m.


      • Anuj Jain

        Anuj JainAnuj Jain

        Author Reply

        it is not working for my code….. 🙁


        • Simon Ng

          Simon NgSimon Ng

          Author Reply

          Could you show me the error?


          • Anuj Jain

            Anuj JainAnuj Jain

            Author

            There is no error message, but it is not displaying the delete button. It is working same as it was working after the previous tutorial.


          • champcar2000

            champcar2000champcar2000

            Author

            In the simulator, to get the Delete button to show, click the mouse – hold – then swipe to the left.


          • Anuj Jain

            Anuj JainAnuj Jain

            Author

            it works…..thanx…. 🙂


          • Vivek Pansara

            Vivek PansaraVivek Pansara

            Author

            still not getting delete button…


  • Xavier Alfeiran

    Great tutorials so much easy to learn with your guides.


  • Ivan

    IvanIvan

    Author Reply

    It gives me an error when I use the objectForKey function of NSDictionary to load the data. Is there some other way to do it?


  • champcar2000

    ..


  • champcar2000

    When I run the simulator and tap the Delete button on a row, it crashes the program.

    It appears that this is because I’ve done lessons 1-7 so my app has already been changed to use a property list, but this lesson still expects the app to be using a hard-coded array for the data. Is this the case??

    Thanks in advance.


  • Sunny

    SunnySunny

    Author Reply

    For the delete button, is the text is fixed ?
    or can I change the word of the button from “Delete” to something else?
    because I want to make a button for user to redirect to another page
    means that if they tap on the table cell, the application will bring them to detail page
    but when they tap on the button, they will be redirected to another page.


  • Matthew Kwan

    If you have implemented the Property List in tutorial 6, then coming here to remove the row from the array, you will get an error. To fix the error you just have to change NSDictionary to NSMutableDictionary.

    By the way all your tutorials are awesome, very informative and easy to follow. Good job buddy!


  • Thomas Moore

    That was pretty easy! Loving the tutorials. Great work Simon!


  • abbiya

    abbiyaabbiya

    Author Reply

    you should write more dude.. great work. thanks


  • Pramodh Bettadapura

    Hi Simon, after creating custom cell i made the above changes with edit button, but on click of edit button the cell resizes but not the text entered can you please help!


  • Guest

    GuestGuest

    Author Reply

    You might consider rewriting this tutorial to use the deleteRowsAtIndexPaths:withRowAnimation: method instead of reloadData.

    http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableView_Class/Reference/Reference.html


  • steveluscher

    You might consider rewriting this tutorial using the deleteRowsAtIndexPaths:withRowAnimation: method instead of reloadData.

    http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableView_Class/Reference/Reference.html


  • Mark Thien

    Mark ThienMark Thien

    Author Reply

    I changed to NSMutableArray and still getting error:

    Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘-[__NSCFArray removeObjectAtIndex:]: mutating method sent to immutable object’

    I am using property list file:

    NSString *path = [[NSBundle mainBundle] pathForResource:@”recipies” ofType:@”plist”];

    recipies = [dict objectForKey:@”recipyName”];


  • Klaus Brunckhorst

    Great tutorial. Thanx!

    In order to work with the example from the previous chapter I used ‘mutableCopy’ to fill the Arrays from the plist:

    [..]

    @implementation HalloWorldViewController
    {
    NSMutableArray *tableData;
    NSMutableArray *thumbnails;
    NSMutableArray *prepTime;
    }

    – (void)viewDidLoad
    {
    [super viewDidLoad];

    // Find out the path of recipes.plist
    NSString *path = [[NSBundle mainBundle] pathForResource:@”recipes” ofType:@”plist”];

    // Load the file content and read the data into arrays
    NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
    tableData = [[dict objectForKey:@”RecipeName”] mutableCopy];
    thumbnails = [[dict objectForKey:@”Thumbnail”] mutableCopy];
    prepTime = [[dict objectForKey:@”PrepTime”] mutableCopy];
    }

    [..]

    – (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
    {
    // Remove the row from data model
    [tableData removeObjectAtIndex:indexPath.row];
    [thumbnails removeObjectAtIndex:indexPath.row];
    [prepTime removeObjectAtIndex:indexPath.row];

    // Request table view to reload
    [tableView reloadData];
    }

    [..]


    • indra tulku

      very helpful, thank you


    • paul

      paulpaul

      Author Reply

      Thanks Klaus!


    • Phil

      PhilPhil

      Author Reply

      I’m new to Obj-C and iOS programming, I’m sorry if these are silly questions.
      When we define tableData, why we have to call method mutableCopy? I checked reference of instance method objectForKey, its return type is “id”.
      1) Is the “id” type not mutable?
      2) Does it mean we have to concern if mutable type is needed for every single object?


    • Jhlx

      JhlxJhlx

      Author Reply

      Thank you!


    • vishal

      vishalvishal

      Author Reply

      why mutablecopy?


  • Nidhi

    NidhiNidhi

    Author Reply

    super awesome 🙂


  • Khalid Mehmood Awan

    “Here, model-view-controller is another example of SoC. The core idea behind MVC is to clearly separate user interface into three areas (or groups of objects) that each area is responsible for a particular functionality. As the name suggests, MVC breaks an user interface into three parts:”

    here you are saying “user interface” , why not say “application instead of “user interface” ?


  • Khalid Mehmood Awan

    Hi Simon, I am using macbook pro with a normal USB mouse. I find it very difficult to swipe for the purpose to delete a table row. Sometimes it works while most of the time it does not.

    is there any way to do it easily ?

    khalidmehmoodawan at gmail


  • Khalid Mehmood Awan

    Excellent tutorials 🙂


  • Lucas Ramos

    Hey, everybody! Thanks Matthew for the update.
    Now, if you’re following the tutorial, beyond changing the dictionary to Mutable Dictionary,
    You have to add:
    NSMutableArray *thumbnails;
    NSMutableArray *prepTime;[thumbnails removeObjectAtIndex:indexPath.row];

    And
    [prepTime removeObjectAtIndex:indexPath.row];
    [thumbnails removeObjectAtIndex:indexPath.row];

    In order to it work.


  • 刘雨辰

    刘雨辰刘雨辰

    Author Reply

    I can delete a row using the tutorial’s code, but it has no animation or aesthetic, how to fix it, thanks.


  • shailesh

    shaileshshailesh

    Author Reply

    Superb tutorial 🙂


  • aamir khan

    aamir khanaamir khan

    Author Reply

    it is deleted my tables cells data helpfull tutorials great work


  • Learner

    LearnerLearner

    Author Reply

    didn’t any delete button shows, please post the full .m file code pls pls pls


  • learner

    learnerlearner

    Author Reply

    It cant delete last row


  • priyank

    priyankpriyank

    Author Reply

    Hi,first of all thanks for this “Great tutorial”.I’m new in ios development…can u plz explain how to install sqlite and insert and retrive data from sqlite.


  • kaushik kumar

    i did the same to delete the cell but its showing an exception as……’-[__NSCFArray removeObjectAtIndex:]: mutating method sent to immutable object’…but i am using nsmutable array


  • Ankit

    AnkitAnkit

    Author Reply

    I write the code of delete button. But delete button is not showing.Plz help me.


    • wahiba

      wahibawahiba

      Author Reply

      In the simulator, to get the Delete button to show, click the mouse – hold – then swipe to the left.


  • Ben

    BenBen

    Author Reply

    Great tutorials. Just a simple side note… Being French and a cook in my spare time, I really have to point this out : One does not say crême brelée but Crême Brûlée (which literraly means : burnt cream)


  • abDullah

    abDullahabDullah

    Author Reply

    Excellent tutorials …… keep it coming 😉


  • Chilly

    ChillyChilly

    Author Reply

    Great tutorial. For me the only thing missing is rearranging the cell assignments after a row is delete


  • Abdurrahman Mubeen Ali

    Nice & easy tutorial. How can I get the DELETE button on the left of the text?


  • Sharad Goyal

    i did it but it is not showing “delete” button please help me in this program


  • Patel Kaushik

    i make table view apps by custom cell ,i implement delete row from table but can’t delete

    please give me help for delete table data which is created by custom cell …


  • sergtk

    sergtksergtk

    Author Reply

    How to update existing data when model is changed? It is easy to create Mapping Model in Xcode, specify mapping between properties. But is not clear what to do next with it and how to use it. Are there any tutorial on this subject here? Thanks


  • Developer

    DeveloperDeveloper

    Author Reply

    How do I save what has been deleted? Example: User deletes an item and then closes the app. When the user reopens the app the item is fully deleted and does not just reappear. Thanks


  • Rubin Zubin

    Suppose if i want to add items or row to this then ?


  • Kenmux De

    Kenmux DeKenmux De

    Author Reply

    the source code is ok? why cant i see the delete button, neither with my ipad nor the iphone simulator?


    • Paco

      PacoPaco

      Author Reply

      Hi,
      I had the same problem and it turned out that the table view was too big to fit in the screen. Try to half the width of the table view and see if you still can’t see the delete button. If your problem is effectively the same as mine then you have to play with the size restrictions on the main story board. Unfortunately I am not advanced enough to tell how to do it. Good luck 🙂


  • Rithik Dharma

    that one was really good…!


  • Kritbovorn Taweeyossak

    why when I run app again , the data still have full


  • le van pha

    le van phale van pha

    Author Reply

    how to remove check mark when selected row again? thank!


  • Toqeer Ahmad

    Thank You Sir! 🙂
    It helps me a lot ..


  • Charles

    CharlesCharles

    Author Reply

    I followed this steps but in the end after I press end the whole app freezes for a second and then restarts completely, to the point I got to open it again, with no changes whatsoever. Why is that happening?


    • Charles

      CharlesCharles

      Author Reply

      NVM, after founding my mistake Ill go commit suicide in a corner.


  • Nij

    NijNij

    Author Reply

    in commitEditingStyle method, is it necessary to write following lines?

    [tableView deleteRowsAtIndexPaths:[NSMutableArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic] ;

    and yeah very easy to understand ur tutorials thanks to u,, m new to iOS developing.


  • sheikh306

    sheikh306sheikh306

    Author Reply

    great to learn here (Y) keep going on


Shares