Skip to end of metadata
Go to start of metadata

Most mobile apps development involved in working with data – at least presenting a list of data to the user interface. The iOS platform ships with versatile user interface components that allows you to present a list of items, navigate through hierarchically structured data, present an indexed list of items, as well as present a selectable list of options.

At the heart of the data components in iOS are table view and collection view. The table view is widely used in most iOS apps found in the App Store since it provides high performance UI virtualization and a number of flexibility. On the other hand, collection view is more suitable to apply on the iPad, although it’s also possible to utilize it on the iPhone in certain cases.

Programming with the table view and collection view typically require a lot of code which involve a number of processes such as configuring the data source and the delegate. In addition, these data components require a deep understanding on the table hierarchy and cell reuse which are important aspects to build high performance data presentation. The implementation process is considerably sensitive, which means that a simple failure or incorrect implementation will lead to random crash and unexpected behaviors in both table and collection view.

Crosslight takes care most of the details in the table view implementation for you such as the data source provider, UI virtualization, memory allocation and automatic object disposal, smooth animation and much more. Crosslight makes data presentation a breeze – thanks to the MVVM design pattern built to the core of Crosslight. In most cases, you only need a single line of class declaration to present your data – throwing away nearly hundred line of code typically required to implement such tasks. As the results, you can expect exponentially increased productivity and time saving in building great iOS apps.

Displaying Simple Data

Presenting data in iOS with Crosslight is a breeze. You start with a view controller that derives from UITableViewController<TViewModel> Class – a specialized table view controller that supports ViewModel and automates most data-related tasks based on the supplied ViewModel.

The results of the above simple declaration can be seen in the image below.


Note that the items presented in the table view controller is queried from the ViewModel through the binding definitions.

You typically group the binding definitions logically to a class, and then easily import it to your view controller through the ImportBindingAttribute Class – also shown in the example above. 

For more information about the basics of data binding in Crosslight, see Understanding Binding Providers.

Displaying Grouped Data

Similar to the simple data presentation, displaying grouped data in Crosslight took only a property setting. Simply override the ShowGroupHeader property and return a true value to show the data in groups.

Keep in mind that the underlying ViewModel is required to supply the grouped data in the items source. 

For more information, see Displaying and Customizing Group List.

Customizing Group Style

You can present grouped data in two group styles – plain group or sectioned group. In most cases, you typically use the plain group style such as shown in the previous section.

However, if you prefer, you can use the sectioned group style by simply overriding the TableViewStyle property.

The results look like the image below.




Showing Group Section Index

If your data contains fairly large number of groups, you may want to show the group index to allow users to easily jump to a specific group. 

You can easily enable this feature through a property setting – and let Crosslight do the rest by automating the index presentation and group locating process. By default, Crosslight shows all alphabets and adds the # to the last index which conforms to the Apple standards.

The C# represents the groups whose name started with number or non-alphabet.

The following illustration shows the results of the example above.



Enable Searching

In iOS, you typically add the search functionality by presenting a search bar on top of the table view. Crosslight has streamlined the searching functionality, allowing you to enable searching in just a property configuration. When enabled, the search bar will be automatically displayed on the top of the table view. In addition, Crosslight also handles most of the user experience in depth details such as applying smooth animation when the search bar becomes active or inactive, as well as state persistence when user navigates to the detail and back to the search results.

To enable searching, override the AllowSearching property such as shown in the example code below.

When user types on the search bar, the table view controller automatically raises the Filter method of the ViewModel – if the ViewModel implements IFilteredSource interface. By default, certain data-aware ViewModel base classes such as ListViewModelBase that ships with Crosslight already implement the necessary interfaces to streamline the data operations. 

For more information about filtering data in ViewModel, see Implement Searchable List. For more information about the ViewModel base classes available in Crosslight, see Selecting a ViewModel Base Class to Get Started.

Note that you can also hide the search bar initially by configuring the HideSearchBarInitially property. When set to true, the table view will start the screen offset from the first row. Users can access the search bar by scrolling downward.

The following illustration shows the results.

Enable Search Scope

In addition to the vanilla search bar, iOS provides a common user interface that allows users to select the scope of the search. The scope affects the results of the search query, for instances, users may want to perform search that is scoped to a location, a category, and so on.

For more information about filtering data in ViewModel, see Implement Searchable List.

Again, Crosslight makes it extremely easy to leverage this feature. Simply provide an array of string that represent the search scopes to the SearchScopes property such as shown below.

The following illustration shows the results of the example above.

At runtime, the search scope will now be visible when users activate the search bar. The selected scope will be passed to the Filter method in the same way the search keyword does.

The following example shows how to implement the Filter method in the ViewModel to perform query based on keyword and scope.

For more information about filtering data in ViewModel, see Implement Searchable List.

Customizing Cell Styles

The table view comes with four predefined cell styles that you can quickly customize through a property configuration. The supported cell styles are: Default, Right Detail, Left Detail, and Subtitle.
To customize the cell style, override the CellStyle property and provide the cell style value that you desire.

For presentation consistency, you should use only one kind of cell style at a time. Most table view configuration in particular and iOS view programming in general perform initialization only once at object creation phase. Dynamic changes to the view elements at runtime are rare and not encouraged – which is one of the reasons why native iOS apps typically perform with better performance. Crosslight reflects the design naturally.

As the results, the CellStyle property, similar to many other properties, are designed in a way that prevents the value to be changed at runtime. These properties typically do not have setter. In order to change the value, you override the property and provide the desired value in the getter.

The following illustration shows the various predefined cell styles supported in Crosslight for iOS.

Using Custom Cell Template 

In addition to the built-in cell styles described earlier, the table view also allows you to bring your own custom style – or also known as custom cell template. This means that you can design your own user interface and apply it to the table view.

Crosslight supports the custom cell template feature, and more importantly, provides an elegant approach to add data binding capabilities to the view template. Combined with the cell reuse support for high performance UI virtualization, Crosslight seamlessly provide the required data item on demand according to the cell template definition. As the results, you can achieve this task in just a few line of code, eliminating away hundreds lines of code typically needed to achieve such task.

Leveraging a custom cell template in the table view involves a few steps. First, create a custom table cell which derives from the standard UITableViewCell class such as shown below.

Next, create a view (also known as interface definition typically with .xib extension) with the same name as specified in the Nib static property of the custom class described above. Double click the CustomTableCell.xib file in Xamarin Studio and it will open up Xcode. Once you finished the design, make sure that the view’s class is set to CustomTableCell and the table view cell’s Identifier is set to CustomTableCell. This allows the view to connect to the appropriate class, and enables the table view cell to correctly reuse the cell to deliver the best performance possible.

The following screenshot shows the overview of custom table cell design in Xcode.

Once you have the custom table cell ready (both the class and the view), the final step is creating a table view controller that consumes the custom table cell. With Crosslight, you only need a few property configuration to achieve this task.

The example code above is self-explanatory. The CellStyle is overridden to use the Custom style, and the two next properties are crucial for table view to pick up the custom template properly. Crosslight provides a class called UIViewTemplate which you can instantiate and pass in the UINib instance that represents the custom table cell. Finally, the CellIdentifier property should reflect the identifier that you configure in the Xcode designer – see the highlighted rectangle in the previous screenshot.

Another noteworthy point is that if your custom table view cell has different height than the default, you should inherit the Crosslight’s default data source adapter and return the desired height in the GetHeight method of the adapter.

Here’s the complete sample code with the configured height.

With the latest enhancements in Crosslight 2.4, you no longer need to create a custom table source to work with a table cell with a custom height. Crosslight's table view component now automatically detects the row height as specified in the XIB at runtime. All you need is simply specifying the custom cell in the provided CellTemplate property. For more information, see Crosslight 2.0 Update 4 Release Notes.

Given that you have properly configured the ViewModel and the binding definitions in the binding provider class, you should see the results similar to the following image.

In addition to the item template, you can customize the section header and footer templates in the same way. The properties are represented in SectionHeaderTemplate and SectionFooterTemplate respectively.

For the step-by-step instructions to customize cell template, see Create Custom Cell Template for iOS UITableView. For more information about configuring data binding in item template, see Customizing Item Styles.

Customizing Item Styles

Your apps look better when the items are presented more intuitively, for instances, sold inventories are formatted with strikethrough text effect, important tasks appear with more attractive color, and so on. Customizing item styles in iOS require fairly large number of code and involve a number of steps such as updating the view’s elements from different entry points and synchronize model and view manually.

Based on MVVM design pattern, Crosslight provides techniques called item style selector which enable you to easily customize item styles which automatically synchronize the views when the affected properties of the model has changed – thanks to the two-way data binding made possible in Crosslight.

In general, you create a class that implements the style selector logic in the shared application layer, then bind the class through a converter to the table view in the binding provider. There are no configurations required at the iOS layer.

The following example shows how to set a strikethrough text style for items marked as sold.

The definition for the label in the binding provider class looks like the following.

The ItemBindingDescription Class represents the binding information specific to the view elements in the cell template.

In the above example, it binds the IsSold property to the TextLabel’s StyleAttributes. In the converter class, an appropriate style will be provided based on the value of the IsSold property. If the item’s IsSold is true, the label will be styled as strikethrough, otherwise the normal style will be used.

See the results in the image below.

Capturing Selection

In addition to displaying a list of items, the table view can also be configured to capture selection which is a common requirement in most data-driven apps. When users tap on one or more items, a selection indicator (checkmark) with appear on the right edge of the item which indicate that the item is selected.

Configuring the table view as choice selection is easy and straightforward. First, configure the InteractionMode property and return the ChoiceInput value to the property. In addition, you can choose whether users are allowed to make multiple selections. To do so, provide the ChoiceInputMode property with the Multiple value such as shown in the following example.

The following illustration shows the results of the example above.

When bound to the SelectedItem or SelectedItems property depending on the ChoiceInputMode, the table view automatically synchronize the changes to the ViewModel, allowing you to intercept and write user interaction logic that responds to the changes – all within the shared application layer.

Editing Table View

The table view component is not only great for presenting data, it also sports sophisticated pre-built features that make data editing a breeze. When the editing is enabled on the table view, users can swipe a cell to delete the particular item.

Most iOS apps are designed with a common data editing pattern where the Edit button is provided in the navigation bar. Users can tap on the button and activate the edit mode of the table view. The editing mode of the table view allows users to perform an action to a single item or multiple items based on the editing options as well as re-ordering items by dragging the move handle/grip that appears in the right edge of the table.

Crosslight streamlines the table view editing with only a few property sets – thanks to the powerful MVVM framework built right at the core of Crosslight.
To enable editing and configure the options, provide the desired values to the EditingOptions property. The following example shows how to enable editing with multiple selection mode. It also demonstrates how to show the toolbar and register a Delete button in the toolbar when the table view enters editing mode.

Notice that the above code contains only simple view-related initialization. The actual user interaction logic resides in the shared application layer – typically in the ViewModel – which is the essence of the MVVM design pattern that Crosslight heavily built upon.

The following illustration visualizes the table view editing UI pattern and the result of the above example.

As the table view editing pattern is obvious and solid, Crosslight provides a built-in ViewModelBase that takes care most of the editing details. It includes editing related members that you can bind to the bindable properties described above. Instead of deriving your ViewModel from ListViewModelBase<T>, you should derive from EditableListViewModelBase<T> instead.

The EditableListViewModelBase provides editing related members that you can easily consume through data binding such as:

  • AddCommand
  • EditCommand
  • DeleteCommand
  • ReorderCommand
  • ToggleEditModeCommand
  • IsBatchUpdating
  • IsEditing
All the commands above are raised automatically when table view performs its actions – except AddCommand and EditCommand which are not generally performed by the table view. Instead, you typically bind the AddCommand to a button in the navigation bar which presents a new data form. While the EditCommand is designed for explicit item editing which is rare in iOS apps, you may use it in other platforms and still be able to streamline your application logic in the same ViewModel.

In addition, there are also dozens of virtual methods that you can simply override based on your needs.
At the data binding end, the table view recognizes several bindable properties that you can configure in the binding provider. The following example shows the binding definitions related to the table view editing which you can streamline in a binding provider class.

The command pattern used in the ViewModel such as EditCommand, DeleteCommand and ReorderCommand enables you to streamline all the user interaction logic in the ViewModel. In addition, the commands allow you to intercept the pre-action and post-action implementation. For examples, you can put certain conditions where a particular item can be re-ordered or not, and where it requires repositioned after processing. The table view automatically recognizes what’s happened with the results in the ViewModel and synchronize accordingly. In short, all you need to do is simply programming the user interaction logic in the ViewModel.

Responding to Delete Action

When bound to the BindableProperties.DeleteItemCommand and users tapped on the delete button in the table view, it will automatically invoke the DeleteCommand simplementation in the ViewModel. The following example shows the delete command implementation in the ViewModel.

Responding to Reorder Action

To enable reorder feature in table view, you provide the AllowReorder flag to the EditingOptions property.

The following example shows the example of reorder command implementation in the ViewModel.

The ReorderCommand implementation in Crosslight streamlines the programmability of the original iOS table view reordering mechanism – eliminating away huge amount of code and complexity typically required in iOS. The key lies in the ReorderParameter sent to the ReorderCommand which provides the Action property that you can inspect in the ViewModel.

The table view reordering involves three steps to accomplish its action. First, it asked whether a particular row can be reordered. If so, the reorder control will appear. When users drag an item around, the table view asked whether you want to customize the target reordered index. Finally, when users finished the reorder action, the table view will reposition the moved item accordingly in the user interface. However, developers are required to perform the necessary logic to synchronize the item in the model layer – or to the data persistence.

As seen in the example code above, the first two steps are streamlined in the provided CanExecuteReorder method. You checked against the Action property and determines if the value is QueryState, then return a boolean value indicating whether the particular RowIndex should support reordering. In the CustomizeTarget action, you can set the proposed row index through the ProposedRowIndex property in the provided reorder parameter. Finally, the ExecuteReorder is invoked when the table view finished the reordering action. This is the method that you should override to provide the application logic to respond to the reordering.

The following illustration shows the results of the example above.

An important note in the reorder implementation is to handle the actual repositioning appropriately in the collection source that bound to the table view. Failure to do this will cause table view to produce incorrect behavior as the view presentation no longer matches the underlying collection data source.

Performing Batch Update with Smooth Animation

Crosslight offers streamlined programmability and maximizes code sharing by allowing you write user interaction logic in the shared application layer. However, that doesn’t mean Crosslight sacrifices important user experience features such as animation and performance. In fact, Crosslight iOS is designed to conform to Apple’s strict human interface guidelines – and is optimized for performance.

Unlike other platforms, iOS is a platform that strongly focused on great user experiences and usability that put in thoughtful considerations on numerous scenarios. When multiple items are changing dynamically at runtime – for instances, several new email messages arriving while users delete other messages at the same time – table view can react to these changes in smooth animation instead of just refreshing the data source directly. The smooth animations allow users to intuitively understand what’s happening with the list they’re currently seeing.

Crosslight supports this collective changes with smooth animation – also known as batch update. In the ViewModel, you simply set the IsBatchUpdating property to true before performing collective changes to the collection, then set it back to false afterward.

See the following code for an example of batch update implementation.

As seen in the above example, making changes to the table view can be done as simple as modifying the collection source through the Insert and Remove method. This is made possible thanks to the powerful observable data source implemented in Crosslight’s table view.

Keep in mind that you need to define two-way binding on the IsBatchUpdating property to the table view in the binding provider. To learn about data binding concept, see Understanding Binding Providers.