UIKit.UITableView Class
A table view is used to display and edit hierarchical lists of information. A UITableView is limited to a single column because it is designed for a small screen.

See Also: UITableView Members

Syntax

[Foundation.Register("UITableView", true)]
public class UITableView : UIScrollView

See Also

UICollectionView

Remarks

UIKit.UITableView is a subclass of UIKit.UIScrollView that allows users to scroll the table vertically (the closely-related UIKit.UICollectionView class allows for horizontal scrolling and complex two-dimensional layouts). The table consists of UIKit.UITableViewCell objects that are used to render the rows of the table. These cells have content -- labels, images, etc. -- and can also show accessories such as disclosure arrows or inputs controls. UIKit.UITableViews can enter an edit-mode in which rows can be inserted, deleted, and reordered.

The Xamarin article Working with Tables provides guidance on all aspects of UIKit.UITableView use.

For most use-cases, it is not necessary for application developers to subclass UIKit.UITableView or UIKit.UITableViewController, which provide the generic table behavior. Instead, application developers will generally subclass UIKit.UITableViewSource to populate a table and, often, UIKit.UITableViewCell to customize appearance and row behavior.

Table Parts and Functionality

Classes Overview

The primary classes used to display table views are:

ClassResponsibility
UIKit.UITableView A view that contains a collection of cells inside a scrolling container. The table view typically uses the entire screen in an iPhone app but may exist as part of a larger view on the iPad (or appear in a popover).
UIKit.UITableViewCell A view that represents a single cell (or row) in a table view. There are four built-in cell types and it is possible to create custom cells both in C# or with Interface Builder.
UIKit.UITableViewSource Xamarin.iOS-exclusive abstract class that provides all the methods required to display a table, including row count, returning a cell view for each row, handling row selection and many other optional features. You must subclass this to get a UIKit.UITableView working. (UIKit.UITableViewSource combines UIKit.UITableViewDataSource and UIKit.UITableViewDelegate. These classes are still available if the application developer chooses not to use UIKit.UITableViewSource.)
Foundation.NSIndexPath Contains Row and Section properties that uniquely identify the position of a cell in a table.
UIKit.UITableViewController A ready-to-use UIKit.UIViewController that has a UIKit.UITableView hardcoded as its view and made accessible via the UITableViewController.TableView property.
UIKit.UIViewController If the table does not occupy the entire screen you can add a UIKit.UITableView to any UIKit.UIViewController with its UIView.Frame property set appropriately.

Components of a UITableView

There are two UIKit.UITableViewStyle styles: Plain and Grouped. The Plain style allows the section headers and footers to remain visible as the section is scrolled through, and can optionally support an index that appears along the right edge to quickly scroll to a specific section. The Grouped style displays sections in rounded-rectangles that visually group the rows, and provides a default background image behind the scrolling list. The style of the UIKit.UITableView is specified as an argument to the UITableView(System.Drawing.RectangleF, UITableViewStyle) constructor and cannot be changed. Grouped tables should not provide an index.

Tables consist of the following parts:

ElementAccessed via:Type
Table HeaderUITableView.TableHeaderViewUIKit.UIView
Section HeaderUITableViewSource.GetViewForHeaderUIKit.UITableViewHeaderFooterView
Cells (also called Rows)UITableViewSource.GetCellUIKit.UITableViewCell
Section FooterUITableViewSource.GetViewForFooterUIKit.UITableViewHeaderFooterView
IndexUITableViewSource.SectionIndexTitlesstring[]
Edit mode (includes ‘swipe to delete’ and drag handles to change row order)
Table FooterUITableView.TableFooterViewUIKit.UIView

Section rows, headers, footers, edit controls and the index are displayed as follows:

Populating Table Cells

UIKit.UITableViews are designed to work efficiently with tables with thousands of rows. In order to achieve this, each UIKit.UITableView maintains a reusable cache of UIKit.UITableViewCells only a few items larger than can be shown on the screen at any given time.

A UIKit.UITableViewSource object is responsible for managing the relationship between the relatively few UIKit.UITableViewCells and the data is to be displayed. The UIKit.UITableViewSource's UITableViewSource.NumberOfSections and UITableViewSource.RowsInSection methods allow the UIKit.UITableView to request only the data necessary for the cells on the screen. A specific cell is identified by an Foundation.NSIndexPath, whose Foundation.NSIndexPath.Section and Foundation.NSIndexPath.Rowproperties will specify a unique cell.

As cells are about to be scrolled onto the screen, the UIKit.UITableView automatically calls the UITableViewSource.GetCell method of the UIKit.UITableViewSource object assigned to the UITableView.Source property of the UIKit.UITableView (or, if the application developer prefers, the UITableViewDataSource.GetRow method of the UIKit.UITableViewDataSource object referred to by the UITableView.DataSource property).

The application developer's responsibilities when overriding UITableViewSource.GetCell changed with the introduction of iOS 6. Application developers targeting iOS 6 and later should register a UIKit.UITableViewCell for reuse with the UIKit.UITableView by calling either the UITableView.RegisterClassForCellReuse or UITableView.RegisterNibForCellReuse method. Once that is done, application developers do not need to check for null in their override of the UITableViewSource.GetCell method.

If application developers are using the UITableView.RegisterClassForCellReuse with their own subclass of UIKit.UITableViewCell, that implementation must override the UITableViewCell(IntPtr) constructor and call the base constructor (i.e., MyTableViewCell(IntPtr handle) : base(handle){}).

The application developer overrides the UITableViewSource.GetCell method so that it:

Since the UITableViewSource.GetCell method will be called whenever a cell comes into view, application developers should avoid unnecessary computation.

The UIKit.UITableView's reuse queue is accessed via the UITableView.DequeueReusableCell method, which takes a string identifying the type of UIKit.UITableViewCell to retrieve. In iOS 5 and earlier, that method may return null, in which case the application developer should instantiate a new UIKit.UITableViewCell. In iOS 6 and later, while initializing the UIKit.UITableView, the application developer must use either UITableView.RegisterClassForCellReuse or UITableView.RegisterNibForCellReuse to associate a UIKit.UITableViewCell type and it's reuse identifier so that the method UITableViewSource.GetCell can instantiate instances as necessary.

The following shows a simple example of the UITableViewSource.GetCell method:

C# Example

          public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
          {
          //Attempt to retrieve previously-allocated cell
          var cell = tableView.DequeueReusableCell (this.cellTypeIdentifier);
          //The following check and code-block only necessary in applications that do not use RegisterClassforCellReuse or RegisterNibForCellReuse
          if (cell == null) {
          //No reusable cell, so initialize a new one
          cell = new UITableViewCell (UITableViewCellStyle.Default, this.cellTypeIdentifier);
          cell.Tag = Environment.TickCount;
          }
          
          // Change the state of the cell
          cell.TextLabel.Text = //...etc...
          
          // return the cell
          return cell;
          }
          

Customizing Table Appearance

Other than the UITableView.Style property that specifies whether a UIKit.UITableView is grouped or continuous, the appearance of the table is primarily determined by the UIKit.UITableViewCells, the UIKit.UITableViewHeaderFooterViews used for section headers and footers, and the UIKit.UIViews used for the UITableView.Header and UITableView.Footer properties. The API documentation for UIKit.UITableViewCell describes customization in detail.

Highlighting and Selection

Selecting and highlighting in a UIKit.UITableView follows this sequence:

User ActionUITableViewDelegate (UITableViewSource) MethodsUITableViewCell Properties
Nothing touchedHighlighted == false; Selected == false
Finger down in cellUITableViewDelegate.ShouldHighlightRow is called. If it returns false, processing stops.
UITableViewSource.RowHighlighted is called. Highlighted == true; Selected == false
Finger upUITableViewDelegate.WillSelectRow is called. If it returns null, processing stops. Otherwise, whatever Foundation.NSIndexPath it returns will be highlighted.
UITableViewDelegate.RowSelected is called. UITableViewDelegate.RowUnhighlighted is called. Highlighted == false; Selected == true

Deselecting a UIKit.UITableViewCell follows a similar sequence:

User ActionUITableViewDelegate (UITableViewSource) MethodsUITableViewCell Properties
Nothing touched while some UIKit.UITableViewCell is highlighted.Highlighted == false; Selected == true
Finger taps cell (Deselect gesture)UITableViewDelegate.WillDeselectRow is called. If it returns null, processing stops. Otherwise, whatever Foundation.NSIndexPath is returned will be deselected.
UITableViewDelegate.RowDeselected is called. Highlighted == false; Selected == false
Note:

UITableView caches UIKit.UITableViewCell objects only for visible rows, but caches the heights of rows, headers and footers for the entire table. It is possible to create custom UIKit.UITableViewCell objects with varying heights and custom layouts.

UITableView overrides UIView.LayoutSubviews() so that it calls UITableView.ReloadData only when you create a new instance or when you assign a new UITableView.Source (or UITableView.DataSource).Reloading the table view clears current state (including the current selection). However if you explicitly call UITableView.ReloadData() it clears this state and any subsequent direct or indirect call to UIView.LayoutSubviews() does not trigger a reload.

Related content

Requirements

Namespace: UIKit
Assembly: Xamarin.iOS (in Xamarin.iOS.dll)
Assembly Versions: 0.0.0.0