Xamarin.iOS: Applying Pull To Refresh In TableView

In this article, we will see how we add pull to refresh to the tableview control. Tableview is a very important and most widely used control. Thus, we will be having a lot of the tutorials that focus on the different aspects of it. This is the second one of the tableview series and the other is:

Ingredients
  • Visual Studio 2012 or higher / Xamarin Studio 5
  • Xamarin iOS 6.4.5 or higher
  • Mac OS X Yosemite(10.10) & above.

Procedure

  1. Create a new Application in Xamarin Studio by selecting New Solution from the the welcome screen.



  2. Select iOS app from the installed templates. Now, as you can see, we have a lot of options, like Single View app, Master-Detail app, Tabbed app. These are nothing but pre-defined UI screens for the ease-of-use for the developers. For this tutorial, we will select Single View app.



  3. Now, we will name the app and select the minimum iOS version that our app will support, as shown:



  4. Now, we will name the project, give the location for the solution to be saved, and select the version control for git (if required), as shown:



  5. Now, we can see that the solution file is created and it contains all the required files, as shown below:



  6. Now, we will open ViewController.cs from the solution and import CoreGraphics, System, System.Collections.Generic, System.Threading.Tasks and UIKit. 
    1. using System;  
    2. using CoreGraphics;  
    3. using System.Collections.Generic;  
    4. using UIKit;  
    5. using System.Threading.Tasks;  
  7. Create an object of UITableView, TableSource, UIRefreshControl and List<TableItem> in the ViewController class. 
    1. UITableView table;  
    2. TableSource tableSource;  
    3. bool useRefreshControl = false;  
    4. UIRefreshControl RefreshControl;  
    5. List<TableItem> tableItems;  
  8. To set the title of the app in the ViewDidLoad function, just write,
    1. Title = "Pull to Refresh Sample";  
  9. Now, we will add the TableView properties in the ViewDidLoad function. Also, add the TableView to the View and the RefreshControl to the TableView. Finally, our ViewDidLoad() will look as given below:
    1. public override async void ViewDidLoad()  
    2. {  
    3.     base.ViewDidLoad();  
    4.     // Perform any additional setup after loading the view, typically from a nib.  
    5.   
    6.     Title = "Pull to Refresh Sample";  
    7.     table = new UITableView(new CGRect(0, 20, View.Bounds.Width, View.Bounds.Height - 20));  
    8.     //table.AutoresizingMask = UIViewAutoresizing.All;  
    9.     tableItems = new List<TableItem>();  
    10.     tableItems.Add(new TableItem("Vegetables") { ImageName = "Vegetables.jpg" });  
    11.     tableItems.Add(new TableItem("Fruits") { ImageName = "Fruits.jpg" });  
    12.     tableItems.Add(new TableItem("Flower Buds") { ImageName = "Flower Buds.jpg" });  
    13.     tableItems.Add(new TableItem("Legumes") { ImageName = "Legumes.jpg" });  
    14.     tableItems.Add(new TableItem("Tubers") { ImageName = "Tubers.jpg" });  
    15.     tableSource = new TableSource(tableItems);  
    16.     table.Source = tableSource;  
    17.   
    18.     await RefreshAsync();  
    19.   
    20.     AddRefreshControl();  
    21.   
    22.     Add(table);  
    23.     table.Add(RefreshControl);  
    24. }  
  10. We also add the RefreshAsync() and AddRefreshControl() methods for the UIRefreshControl to perform the PullToRefresh action. 
    1. async Task RefreshAsync()  
    2. {  
    3.     // only activate the refresh control if the feature is available  
    4.     if (useRefreshControl)  
    5.         RefreshControl.BeginRefreshing();  
    6.   
    7.     if (useRefreshControl)  
    8.         RefreshControl.EndRefreshing();  
    9.   
    10.         table.ReloadData();  
    11. }  
    12.  
    13. #region * iOS Specific Code  
    14. // This method will add the UIRefreshControl to the table view if  
    15. // it is available, ie, we are running on iOS 6+  
    16. void AddRefreshControl()  
    17. {  
    18.     if (UIDevice.CurrentDevice.CheckSystemVersion(6, 0))  
    19.     {  
    20.         // the refresh control is available, let's add it  
    21.         RefreshControl = new UIRefreshControl();  
    22.         RefreshControl.ValueChanged += async (sender, e) =>  
    23.         {  
    24.             tableItems.Add(new TableItem("Bulbs") { ImageName = "Bulbs.jpg" });  
    25.             await RefreshAsync();  
    26.         };  
    27.         useRefreshControl = true;  
    28.     }  
    29. }  
    30. #endregion  
  11. Now, we will add a new class, TableSource, to the solution.



  12. Once the file is added, open TableSource.cs and add the code, given below:
    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.IO;  
    4. using Foundation;  
    5. using UIKit;  
    6.   
    7. namespace PullToRefresh  
    8. {  
    9.     public class TableSource : UITableViewSource  
    10.     {  
    11.         List<TableItem> tableItems;  
    12.         protected string cellIdentifier = "TableCell";  
    13.   
    14.         public TableSource(List<TableItem> items)  
    15.         {  
    16.             tableItems = items;  
    17.         }  
    18.   
    19.         public override nint RowsInSection(UITableView tableview, nint section)  
    20.         {  
    21.             return tableItems.Count;  
    22.         }  
    23.   
    24.         public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)  
    25.         {  
    26.             // request a recycled cell to save memory  
    27.             UITableViewCell cell = tableView.DequeueReusableCell(cellIdentifier);  
    28.   
    29.   
    30.             var cellStyle = UITableViewCellStyle.Default;  
    31.   
    32.             // if there are no cells to reuse, create a new one  
    33.             if (cell == null)  
    34.             {  
    35.                 cell = new UITableViewCell(cellStyle, cellIdentifier);  
    36.             }  
    37.   
    38.             cell.TextLabel.Text = tableItems[indexPath.Row].Title;  
    39.             cell.ImageView.Image = UIImage.FromFile("Images/" + tableItems[indexPath.Row].ImageName);  
    40.   
    41.             return cell;  
    42.         }  
    43.   
    44.         public override nint NumberOfSections(UITableView tableView)  
    45.         {  
    46.             return 1;  
    47.         }  
    48.  
    49.  
    50.         #region -= editing methods =-  
    51.   
    52.         public override void CommitEditingStyle(UITableView tableView, UITableViewCellEditingStyle editingStyle, NSIndexPath indexPath)  
    53.         {  
    54.             switch (editingStyle)  
    55.             {  
    56.                 case UITableViewCellEditingStyle.Insert:  
    57.                     tableItems.Insert(indexPath.Row, new TableItem("(inserted)"));  
    58.                     tableView.InsertRows(new NSIndexPath[] { indexPath }, UITableViewRowAnimation.Fade);  
    59.                     break;  
    60.   
    61.                 case UITableViewCellEditingStyle.None:  
    62.                     Console.WriteLine("CommitEditingStyle:None called");  
    63.                     break;  
    64.             }  
    65.         }  
    66.   
    67.         public override bool CanEditRow(UITableView tableView, NSIndexPath indexPath)  
    68.         {  
    69.             return true;   
    70.         }  
    71.   
    72.         public override UITableViewCellEditingStyle EditingStyleForRow(UITableView tableView, NSIndexPath indexPath)  
    73.         {  
    74.             if (tableView.Editing)  
    75.             {  
    76.                 if (indexPath.Row == tableView.NumberOfRowsInSection(0) - 1)  
    77.                     return UITableViewCellEditingStyle.Insert;  
    78.                 else  
    79.                     return UITableViewCellEditingStyle.Delete;  
    80.             }  
    81.             else  // not in editing mode, enable swipe-to-delete for all rows  
    82.                 return UITableViewCellEditingStyle.Delete;  
    83.         }  
    84.   
    85.         public void WillBeginTableEditing(UITableView tableView)  
    86.         {  
    87.             tableView.BeginUpdates();  
    88.   
    89.             tableView.InsertRows(new NSIndexPath[] {  
    90.                     NSIndexPath.FromRowSection (tableView.NumberOfRowsInSection (0), 0)  
    91.                 }, UITableViewRowAnimation.Fade);  
    92.             tableItems.Add(new TableItem("(add new)"));  
    93.   
    94.             tableView.EndUpdates();  
    95.         }  
    96.  
    97.         #endregion  
    98.     }  
    99. }  
    This class is used to implement the abstract class UITableViewSource. Thus, we define the basic functions required for a TableView. RowsInSection is used to determine the number of rows present in a section, NumberOfSections are used to determine the number of sections; the TableView is divided and the GetCell defines the UITableViewCell that will be rendered for a particular row. We also add methods, which helps in depicting the PullToRefresh in action by adding an insert operation in the TableItems collection. Some of the editing methods used are CommitEditingStyle, which defines that the TableView cell is being edited and a new cell is being added by adding a new item in the TableItems collection and a new row in the TableView. WillBeginTableEditing defines the animations and how the table will show the addition of the new cell.

  13. Now, we will add another class, TableItem, to the solution for the customized cell style. Once the file is added, open TableItem.cs and add the code, given below:
    1. using System;  
    2. using UIKit;  
    3.   
    4. namespace PullToRefresh  
    5. {  
    6.     public class TableItem  
    7.     {  
    8.         public string Title { getset; }  
    9.   
    10.         public string ImageName { getset; }  
    11.   
    12.         public UITableViewCellStyle CellStyle  
    13.         {  
    14.             get { return cellStyle; }  
    15.             set { cellStyle = value; }  
    16.         }  
    17.         protected UITableViewCellStyle cellStyle = UITableViewCellStyle.Default;  
    18.   
    19.         public UITableViewCellAccessory CellAccessory  
    20.         {  
    21.             get { return cellAccessory; }  
    22.             set { cellAccessory = value; }  
    23.         }  
    24.         protected UITableViewCellAccessory cellAccessory = UITableViewCellAccessory.None;  
    25.   
    26.         public TableItem() { }  
    27.   
    28.         public TableItem(string title)  
    29.         { Title = title; }  
    30.   
    31.     }  
    32. }  
  14. Now,  we run the app o the iPhone simulator of our choice (I did it on iPhone 6S) and it looks, as shown below:



  15. Once we pull to refresh the app, it looks:

     

  16. To see if it has refreshed or not, we have added an item in the AddRefreshControl method. Thus, it looks, as shown below:

Make some beautiful apps using Xamarin.iOS and tweet your queries to @adiiaditya. If you want to fork this project, visit myGit.


Similar Articles