First and foremost, your iOS app should have an application delegate which commonly implemented in the AppDelegate.cs. The application delegate should derive from Intersoft.Crosslight.iOS.UIApplicationDelegate Class, see the example below.
In addition, Crosslight iOS apps should have an application initializer implementation which typically contained in the AppInitializer.cs file under the Infrastructure folder. The application initializer class should implement the IApplicationInitializer Interface which is automatically discovered by Crosslight at runtime.
The AppInitializer class provides methods that connect the apps to the core services in the shared application layer and prepares the necessary configuration for your apps during startup. It looks like the following sample.
At this point, your iOS project should be ready and you can start adding specific functionalities to your app.
Adding MVVM-enabled View Controllers to Your Project
Assuming that you have the ViewModel and binding provider ready at the shared application layer, you may want to start creating views that consume the ViewModel and present them in your iOS apps. This process involves two steps, creating the view controller that manages the views and optionally create the interface definition that resembles the views.
The view controller in iOS represents the controller in the MVC design pattern. In Crosslight, view controller is implemented as view context. A view context has a number of important responsibilities such as establishing connection to the view model, perform automatic binding registration and disposal, and more. Consequently, Crosslight ships with a vast array of view controllers that include built-in ViewModel support which hides the complexity of the controller and positions the ViewModel to serve as the actual mediator between the model and the view – as in common MVVM apps.
The most basic view controller in Crosslight iOS is UIViewController<TViewModel>. The following code shows the example of a view controller that consumes LoanCalculatorViewModel as its view model and loads the LoanCalculatorView.xib to its root view hierarchy.
The ImportBinding attribute instructs the view controller to automatically import binding definitions from the specified binding provider. This allows you to streamline all your binding definitions to a logical class, and reuse them in iOS and Android projects. For more information, see Importing Binding Providers to View.
Since Crosslight produces native platform-specific views, you can use the standard Apple development tools, Xcode, to build user interface for iOS apps. The main interface definition for iOS apps is definitely contained in a storyboard file, or an XIB file for control templates. To give a name to the control which will be used in data binding, simply create an outlet in Xcode. Behind the scene, Xamarin will automatically create the properties in an auto-generated design-time file.
To learn more about designing views in Xcode, see Using Interface Builder.
In addition to Xcode, Crosslight iOS also provides full support for Xamarin iOS storyboard designer, allowing you to quickly discover Crosslight components in the toolbox, then simply drag the desired components to the designer surface. Albeit some designer constraints, Xamarin iOS designer provides seamless integration to the IDE itself, making certain tasks simpler, for instance, providing a name for a control can be done by simply entering a value in the property window.
For more information, see Working with iOS Universal Storyboards.
Common View Context Members
Every view context implementation shares common characteristics such as the ViewModel property which returns the same type as defined in the class generic template. Since you can access the ViewModel instance that associated to the view controller at runtime, you are open to write your own custom implementation in case you developed your own controls that are not covered in the pre-built Crosslight binding adapters.
In addition to the ViewModel property, there are a number of methods that you can override to intercept a particular life cycle of the view context. The following list describes the virtual methods ordered by the life cycle sequentially.
By default, Crosslight already ships with default implementation for the above methods. In most cases, you override the InitializeView to perform additional initialization to the view such as creating a view element at runtime or configuring the view background.
The following example shows how to set the view's background in InitializeView method.
Registering a View Identifier at Runtime
In the previous section, you’ve learnt how to define a view identifier using interface builder. However, this is only possible when the views are defined in the interface definition. Often times, there are certain type of views that you cannot define in the interface builder – or views that you would like to create dynamically at runtime.
To achieve this scenario, Crosslight provides a method that you can use to register a view identifier to a view element at runtime. Once the view is associated to an identifier, it will work normally as if it were defined in the interface definition. This means that any binding definitions that target the particular identifier will be applied consistently.
The following example shows how to create a UIBarButtonItem and registers a view identifier to it. The most ideal place to initialize additional view-related tasks is during initialize view of the view context life cycle.
In the example above, the RegisterViewIdentifier method registers the ClearButton identifier and associate it to the clear button.
This powerful feature lets you achieve virtually any complex scenarios that involve dynamic view creation at runtime while leveraging the sophisticated data binding features in Crosslight.
Registering Binding Description Manually
The most recommended way to register binding definitions to your view is by importing the binding provider through the ImportBinding attribute such as explained in the earlier sections. However, there are times when it’s not ideal to register the binding definitions in the binding provider. For instance, in the case when a particular definition applies only in iOS project, it makes perfect sense to register the definition only in the particular view controller.
To add binding description manually in a view controller, you use one of the AddBinding method overloads such as shown in the following example.
Setting Bindable Property Value at Runtime
One of the basic tasks that you may encounter is setting the value of bindable properties at runtime. In most cases, bindable property is used during binding definition – typically in the binding provider class. Since a bindable property can participate in two-way binding mode – either the value is propagated from the model or from the control – it is possible for you to modify the value at runtime.
You use the SetPropertyValue extension method to set the value to a particular bindable property. In two-way binding mode, setting the property value will reflect the control’s intrinsic value and automatically synchronize the new value to the model.
The following example shows how to set the HideKeyboardOnReturn property to a textbox which instructs the iOS system keyboard to be dismissed when users tapped on the Return key.
Automatically Fit ScrollView to Content Size
In iOS, there are no layout controls similar to panels in Windows Phone. As such, the view elements are laid out individually relative to the parent container’s coordinate system. In most cases, your view may have a number of view elements that could possibly exceed the height of the screen. It’s always recommended that you wrap all view elements within a UIScrollView.
However, UIScrollView could not automatically calculate the required height of the view elements due to the lacking of layout management in iOS. Crosslight makes it easy to fit the UIScrollView size to the desired height based on the view elements contained in the UIScrollView.
To achieve this scenario, simply override the AutoFitContentSize property and return a true value such as shown in the following example.
Automatically Scroll to Visible Element
By default, iOS doesn’t provide built-in features for user interaction-related tasks due to the flexibility and the dynamic of the views that it provide. For example, the tapped text field will not be automatically shifted up which makes it covered by the keyboard underneath. See the following illustration.
Optimized for line-of-business scenarios, Crosslight provides a time-saving feature to address this scenario which you can enable in a simple property set. To scroll the content automatically to visible tapped element, simply override the AutoScrollToVisible property and returns a true value.
Hide Keyboard on Tap
Another time-saving feature that you might frequently use is to dismiss the keyboard when users tap on the empty space in the current view. Similar to the other features above, iOS did not provide an easy way to enable this fairly common feature. Override the HideKeyboardOnTap property of the UIViewController<TViewModel> to enable this feature.
When using a view controller within navigation controller, you can programmatically show a toolbar at runtime during the InitializeView method. Instead of relying on navigation controller's toolbar function, Crosslight provides SetToolbarHidden method at the view controller class which offers automated toolbar state management. Unlike the default iOS toolbar function, the SetToolbarHidden method in Crosslight automatically revert back the toolbar to the original state when the view controller is popped out from the navigation stack. As the result, you have less state to maintain and less code to write.
The following code shows how to show a toolbar programmatically at runtime.
To quickly get started with Crosslight iOS projects, please refer to Getting Started with Crosslight. You will be guided through each step to create a new Crosslight solution with project wizard.
Learning from working samples is often the fastest way to familiarize yourself with Crosslight development. Please refer to the following samples (recommended in order):
Please follow the following links to learn more about Crosslight iOS development: