Xamarin Summary
Xamarin Summary
Xamarin.Forms Fundamentals
Templates
- ControlTemplate
- Defines the visual structure of
ContentView
derived custom controls, andContentPage
derived pages. Control templates separate the user interface (UI) for a custom control, or page, from the logic that implements the control or page.- Create control template with single parent in Resource Dictionary.
- Set
BindingContext="{Binding Source={RelativeSource TemplatedParent}}"
on root view to bind to properties of custom control or useTemplateBinding
markup extension.
- Set
- Set
ControlTemplate
attribute of custom control resource in XAML - A
ContentPresenter
can be placed in a control template to mark where content to be displayed
- Create control template with single parent in Resource Dictionary.
- Defines the visual structure of
- DataTemplate
- Defines the presentation of data on supported controls.
- DataTemplate creation
-
A common usage scenario for a
DataTemplate
is displaying data from a collection of objects in aCollectionView
. The appearance of the data for each cell in theCollectionView
can be managed by setting theCollectionView.ItemTemplate
property. -
Data templates can be created inline, in a
ResourceDictionary
, or from a custom type.-
Creating Inline DataTemplate
<CollectionView.ItemTemplate> <DataTemplate> <Grid> ... </Grid> </DataTemplate> </CollectionView.ItemTemplate>
-
Creating DataTemplate with a Type
<CollectionView.ItemTemplate> <DataTemplate> <local:MyContentView /> </DataTemplate> </CollectionView.ItemTemplate>
-
Creating
DataTemplate
as aResource
<ContentPage.Resources> <ResourceDictionary> <DataTemplate x:Key="myTemplate"> <Grid> ... </Grid> </DataTemplate> </ResourceDictionary> </ContentPage.Resources> ... <CollectionView ItemTemplate="{StaticResource myTemplate}" />
-
-
- DataTemplate selection
- A
DataTemplateSelector
can be used to choose a DataTemplate at runtime based on the value of a data-bound property.- A data template selector is implemented by creating a class that inherits from
DataTemplateSelector
. TheOnSelectTemplate
method is then overridden to return a particular DataTemplate
Example
public class MyDataTemplateSelector : DataTemplateSelector { public DataTemplate ValidTemplate { get; set; } public DataTemplate InvalidTemplate { get; set; } protected override DataTemplate OnSelectTemplate (object item, BindableObject container) { return ((MyItem)item).DateOfBirth.Year >= 1980 ? ValidTemplate : InvalidTemplate; } }
<ResourceDictionary> <DataTemplate x:Key="validItemTemplate"> <Grid> ... </Grid> </DataTemplate> <DataTemplate x:Key="invalidItemTemplate"> <Grid> ... </Grid> </DataTemplate> <local:MyDataTemplateSelector x:Key="myDataTemplateSelector" ValidTemplate="{StaticResource validItemTemplate}" InvalidTemplate="{StaticResource invalidItemTemplate}" /> </ResourceDictionary>
<CollectionView ItemTemplate="{StaticResource myDataTemplateSelector}" />
- Limitations
- The DataTemplateSelector subclass must always return the same template for the same data if queried multiple times.
- The DataTemplateSelector subclass must not return another DataTemplateSelector subclass.
- The DataTemplateSelector subclass must not return new instances of a DataTemplate on each call. Instead, the same instance must be returned. Failure to do so will create a memory leak and will disable virtualization.
- On Android, there can be no more than 20 different data templates per ListView.
- A data template selector is implemented by creating a class that inherits from
- A
- DataTemplate creation
- Defines the presentation of data on supported controls.
Triggers
- Some Triggers (Except EventTrigger for example) can have a collecion of
EnterActions
andExitActions
that isIList
of typeTriggerAction<T>
. EnterActions are executed when the trigger conditions are met and ExitActions are executed when the trigger conditions are no longer met.<Entry> <Entry.Triggers> <Trigger TargetType="Entry" Property="IsFocused" Value="True"> <Trigger.EnterActions> <local:MyTriggerAction1 /> </Trigger.EnterActions> <Trigger.ExitActions> <local:MyTriggerAction2 /> </Trigger.ExitActions> </Trigger> </Entry.Triggers> </Entry>
- PropertyTrigger
<Entry> <Entry.Triggers> <Trigger TargetType="Entry" Property="IsFocused" Value="True"> <Setter Property="BackgroundColor" Value="Yellow" /> </Trigger> </Entry.Triggers> </Entry>
- DataTrigger
- Data triggers use data binding to monitor another control to cause the Setters to get called.
<Button.Triggers> <DataTrigger TargetType="Button" Binding="{Binding Source={x:Reference entry}, Path=Text.Length}" Value="0"> <Setter Property="IsEnabled" Value="False" /> </DataTrigger> </Button.Triggers>
- EventTrigger
- Implement the generic
TriggerAction<T>
class where T is the type of the control such as Entry, or use base class such asVisualElement
to target groups of controls. - Override
Invoke
method.
<EventTrigger Event="Clicked"> <local:MyTriggerAction /> </EventTrigger>
public class MyTriggerAction : TriggerAction<Entry> { protected override void Invoke (Entry entry) { double result; bool isValid = Double.TryParse (entry.Text, out result); entry.TextColor = isValid ? Color.Default : Color.Red; } }
- Implement the generic
- MultiTrigger
- Can have more than one condition. All the conditions must be true before the Setters are triggered.
- Conditions include
BindingCondition
andProperyCondition
<MultiTrigger TargetType="Button"> <MultiTrigger.Conditions> <BindingCondition Binding="{Binding Source={x:Reference email}, Path=Text.Length}" Value="0" /> <BindingCondition Binding="{Binding Source={x:Reference phone}, Path=Text.Length}" Value="0" /> </MultiTrigger.Conditions> <Setter Property="IsEnabled" Value="False" /> </MultiTrigger>
<PropertyCondition Property="Text" Value="OK" />
- State
-
State triggers are a specialized group of triggers that define the conditions under which a
VisualState
should be applied.<Style TargetType="Grid"> <Setter Property="VisualStateManager.VisualStateGroups"> <VisualStateGroupList> <VisualStateGroup> <VisualState x:Name="Checked"> <VisualState.StateTriggers> <!-- Add State Triggers here --> <VisualState.Setters> <Setter Property="BackgroundColor" Value="Black" /> </VisualState.Setters> </VisualState> <VisualState x:Name="Unchecked"> <VisualState.StateTriggers> <!-- Add State Triggers here --> </VisualState.StateTriggers> <VisualState.Setters> <Setter Property="BackgroundColor" Value="White" /> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateGroupList> </Setter> </Style>
- StateTrigger
- The
StateTrigger
class, which derives from theStateTriggerBase
class, has anIsActive
bindable property. AStateTrigger
triggers aVisualState
change when theIsActive
property changes value.
<StateTrigger IsActive="{Binding IsToggled}" IsActiveChanged="OnCheckedStateIsActiveChanged" />
- The
- AdaptiveTrigger
- An
AdaptiveTrigger
triggers a VisualState change when the window is a specified height or width. This trigger has two bindable properties:MinWindowHeight
andMinWindowWidth
<AdaptiveTrigger MinWindowWidth="0" />
- An
- CompareStateTrigger
<CompareStateTrigger Property="{Binding Source={x:Reference checkBox}, Path=IsChecked}" Value="True" />
- DeviceStateTrigger
<DeviceStateTrigger Device="iOS" />
<DeviceStateTrigger Device="Android" />
- OrientationStateTrigger
<OrientationStateTrigger Orientation="Portrait" />
<OrientationStateTrigger Orientation="Landscape" />
- StateTrigger
-
Behaviors
Adds functionality to a control without the need to subclass
- Attached Behaviors
- Attached behaviors are static classes with one or more attached properties.
- An attached property is a special type of bindable property. They are defined in one class but attached to other objects, and they are recognizable in XAML as attributes that contain a class and a property name separated by a period.
- Xamarin.Forms behaviors have replaced attached behaviors as the preferred approach to behavior construction.
- Xamarin.Forms Behaviors
- Create a class that inherits from the
Behavior
orBehavior<T>
class, where T is the type of the control to which the behavior should apply. - Override the
OnAttachedTo
method to perform any required setup. - Override the
OnDetachingFrom
method to perform any required cleanup. - Implement the core functionality of the behavior.
<Entry> <Entry.Behaviors> <local:MyBehavior /> </Entry.Behaviors> </Entry>
- Create a class that inherits from the
Data Binding
- Data binding is the technique of linking properties of two objects so that changes in one property are automatically reflected in the other property. Data binding is an integral part of the Model-View-ViewModel (MVVM) application architecture.
- The target is the object (and property) on which the data binding is set.
- The source is the object (and property) referenced by the data binding.
- The target property must be backed by a bindable property.
- The target object must be an instance of a class that derives from
BindableObject
-
Use
Binding
Markup Extension orSetBinding()
Scale="{Binding Source={x:Reference slider}, Path=Value}" />
Scale="{Binding Value, Source={x:Reference slider}}" />
- Other Markup Extensions
- x:Static: Used when we want to access static properties, fields, or Enum members in XAML elements.
- x:Reference: Used when we want to declare the reference of some named element into some other element of the same XAML Page.
- x:Type: Used when we want to set the type of some attribute to System.Type object.
- x:Array: Used when we want to construct the array of objects of some specific type.
- x:Null: Used when we want to set the value of some attribute to a null.
-
Bindable Properties
-
Binding Mode The binding mode is specified with a member of the BindingMode enumeration:
- Default (OneWay)
- TwoWay – data goes both ways between source and target
- OneWay – data goes from source to target
- OneWayToSource – data goes from target to source
- OneTime – data goes from source to target, but only when the BindingContext changes
-
String Formatting
-
Binding Path
-
Binding Value Converters
-
Relative Bindings
-
Binding Fallbacks
-
Multi-Bindings
-
Command Interface
- Compiled Bindings
Effects
Simplifies customisation, is reusable and paramaterised. Is appropriate for property changes on platform specific control
Steps:
- 1
- 2
- 3
Custom Renderers
Customise appearance and/or behavior. Required to override a method on a platform specific control or when there is a need to replace the platform specific control that implements a Xamarin.Forms control.
Steps:
- 1
- 2
- 3
Gestures
- Tap
- Pinch
- Pan
- Swipe
- Drag & Drop
Navigation
- Hierarchical Navigation
- The
NavigationPage
class provides a hierarchical navigation experience where the user is able to navigate through pages, forwards and backwards, as desired. The class implements navigation as a last-in, first-out (LIFO) stack of Page objects.
- The
- TabbedPage
- The Xamarin.Forms
TabbedPage
consists of a list of tabs and a larger detail area, with each tab loading content into the detail area.
- The Xamarin.Forms
- CarouselPage
- The Xamarin.Forms
CarouselPage
is a page that users can swipe from side to side to navigate through pages of content, like a gallery.
- The Xamarin.Forms
- FlyoutPage
- The Xamarin.Forms
FlyoutPage
is a page that manages two pages of related information – a flyout page that presents items, and a detail page that presents details about items on the flyout page.
- The Xamarin.Forms
- ModalPage
- Xamarin.Forms also provides support for modal pages. A modal page encourages users to complete a self-contained task that cannot be navigated away from until the task is completed or cancelled.
Shell
- Xamarin.Forms Shell reduces the complexity of mobile application development by providing the fundamental features that most mobile applications require, including:
- A single place to describe the visual hierarchy of an application.
- A common navigation user experience.
- A URI-based navigation scheme that permits navigation to any page in the application.
- An integrated search handler.
- Flyout
- Tabs
- Navigation
SOLID
-
Single-responsibility principle
A class should only have a single responsibility, that is, only changes to one part of the software’s specification should be able to affect the specification of the class.
-
Open–closed principle
“Software entities … should be open for extension, but closed for modification.”
-
Liskov substitution principle
“Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.”
-
Interface segregation principle
“Many client-specific interfaces are better than one general-purpose interface.”
-
Dependency inversion principle
One should “depend upon abstractions, not concretions.”
OOD Paterns
- Creational
- Abstract Factory
- The Abstract Factory provides an interface for creating families of related or dependent objects without the need to specify their concrete classes.
- Factory Method
- The Factory Method defines an interface for object creation but let’s the subclass decide which object to create.
- Builder
- The Builder pattern enables a more readable object creation and let’s you specify the fields that are actually needed.
- Prototype
- The prototype pattern helps if objects are expensive to create and new objects will be similar to existing objects. It uses the clone method to duplicate existing instances to be used as a prototype for new instances.
- Singleton
- A Singleton ensures that only one instance of an object is created and that this instance is globally accessible. There are not many occasions where it is acceptable to use a Singleton as it introduces global state. Logging is one meaningful example for the Singleton
- Abstract Factory
- Structural
- Adapter
- The Adapter Pattern works between two independent or incompatible interfaces.
- Bridge
- The Bridge pattern is used to decouple interfaces from implementations, if there are hierarchies in interfaces as well as implementations.
- Composite
- The composite pattern allows to treat a group of objects the same way as a single object. This is for example used in tree-like object structures where a parent node’s operation influences or is dependent on child nodes.
- Decorator
- The decorator pattern allows to add functionality to an object at run-time without altering its structure.
- Facade
- A Facade simplifies the interface to an object or a group of objects “behind” this facade.
- Flyweight
- The Flyweight pattern is applied if lots of objects from one class need to be constructed.
- Proxy
- In this pattern an object is a proxy to something else and can control the creation and access of it.
- Adapter
- Behavioural
- Chain of responsibility
- This pattern creates a chain of receiver objects for a request. It avoids coupling the sender of a request to the receiver and gives multiple objects the chance to handle the request.
- Command
- In the command pattern an object is used to encapsulate all information needed to perform an action or trigger an event at a later time.
- Interpreter
- The Interpreter pattern defines a representation for the grammar of a language and provides the ability to interpret sentences of that language
- Iterator
- The Iterator is used to traverse a container of data to access the container’s elements without the need to know the underlying structure.
- Mediator
- If two or more objects need to cooperate, the Mediator pattern might be applied. Especially if the objects do not know each other, if they should not be tightly coupled, or their interaction is complex, this pattern can help.
- Memento
- The Memento pattern is useful if a certain state of an object should be saved for later usage.
- Observer
- In the observer pattern observer objects subscribe to an observable object to be notified every time the observable changes its data. Observers are loosely coupled and can be added and removed at run-time. With regard to how the observer finally gets the data from the observable, there are two variants: push and pull.
- State
- The State pattern lets an object alter its behaviour when its internal state changes. This pattern is similar to the strategy pattern, but in this case it is decided internally how the objects behaves.
- Strategy
- In the context of the Strategy pattern there exist multiple variants for one algorithm where one variant is chosen to be executed at runtime.
- Template
- The Template pattern defines a structure for sub classes in which steps of an algorithm and their order are defined. This ensures that the sub classes follow the exact same steps, providing better overview and consistency. It also allows to define default implementations for steps that can be overridden by subclasses.
- Visitor
- The Visitor pattern allows to apply one or more operation to a set of objects at run-time without having the operations tightly coupled with the object structure. This let’s you implement double dispatch where a function call to different concrete functions is depending on the run-time type of two objects.
- Chain of responsibility
Xamarin.Android Fundamentals
- Activity LifeCycle
- States
- Active or Running
- Paused
- Stopped / Backgrounded
- Restarted
- Methods
- OnCreate()
- OnStart()
- OnResume()
- OnPause()
- OnStop()
- OnRestart()
- OnDestroy()
- Bundle State
- OnSaveInstanceState()
- The default implementation of OnSaveInstanceState will take care of saving transient data in the UI for every view, so long as each view has an ID assigned.
- OnRestoreInstanceState()
- OnSaveInstanceState()
- Persisteing complex data
- override Java.Lang.Object OnRetainNonConfigurationInstance ()
- read LastNonConfigurationInstance
- States
- Android Services
- Android applications are made up of at least one of the following four primary components: Activities, Broadcast Receivers, Content Providers, and Services.
- An Android service is a component that is designed to do some work without a user interface.
-
Background work can be broken down into two broad classifications:
-
Long Running Task – This is work that is ongoing until explicitly stopped. An example of a long running task is an app that streams music or that must monitor data collected from a sensor. These tasks must run even though the application has no visible user interface.
-
Periodic Tasks – (sometimes referred to as a job) A periodic task is one that is of relatively short in duration (several seconds) and is run on a schedule (i.e. once a day for a week or perhaps just once in the next 60 seconds). An example of this is downloading a file from the internet or generating a thumbnail for an image.
-
-
There are four different types of Android services:
-
Bound Service – A bound service is a service that has some other component (typically an Activity) bound to it. A bound service provides an interface that allows the bound component and the service to interact with each other. Once there are no more clients bound to the service, Android will shut the service down.
-
IntentService – An IntentService is a specialized subclass of the Service class that simplifies service creation and usage. An IntentService is meant to handle individual autonomous calls. Unlike a service, which can concurrently handle multiple calls, an IntentService is more like a work queue processor – work is queued up and an IntentService processes each job one at a time on a single worker thread. Typically, anIntentService is not bound to an Activity or a Fragment.
-
Started Service – A started service is a service that has been started by some other Android component (such as an Activity) and is run continuously in the background until something explicitly tells the service to stop. Unlike a bound service, a started service does not have any clients directly bound to it. For this reason, it is important to design started services so that they may be gracefully restarted as necessary.
-
Hybrid Service – A hybrid service is a service that has the characteristics of a started service and a bound service. A hybrid service can be started by when a component binds to it or it may be started by some event. A client component may or may not be bound to the hybrid service. A hybrid service will keep running until it is explicitly told to stop, or until there are no more clients bound to it. _
-
- Broadcast Receivers
- A broadcast receiver is an Android component that allows an application to respond to messages (an Android Intent) that are broadcast by the Android operating system or by an application. Broadcasts follow a publish-subscribe model – an event causes a broadcast to be published and received by those components that are interested in the event.
- Android identifies two types of broadcasts:
- Explicit broadcast – These types of broadcasts target a specific application. The most common use of an explicit broadcast is to start an Activity. An example of an explicit broadcast when an app needs to dial a phone number; it will dispatch an Intent that targets the Phone app on Android and pass along the phone number to be dialed. Android will then route the intent to the Phone app.
- Implicit broadcast – These broadcasts are dispatched to all apps on the device. An example of an implicit broadcast is the ACTION_POWER_CONNECTED intent. This intent is published each time Android detects that the battery on the device is charging. Android will route this intent to all apps that have registered for this event.
- The broadcast receiver is a subclass of the BroadcastReceiver type and it must override the OnReceive method. Android will execute OnReceive on the main thread,
- Publishing a Broadcast
- A broadcast may be published to all apps installed on the device creating an Intent object and dispatching it with the SendBroadcast or the SendOrderedBroadcast method.
Intent message = new Intent("com.xamarin.example.TEST"); // If desired, pass some values to the broadcast receiver. message.PutExtra("key", "value"); SendBroadcast(message);
Intent intent = new Intent(); intent.SetAction("com.xamarin.example.TEST"); intent.PutExtra("key", "value"); SendBroadcast(intent);
- A broadcast may be published to all apps installed on the device creating an Intent object and dispatching it with the SendBroadcast or the SendOrderedBroadcast method.
- Permissions
- Declare in manifest
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
- Runtime check
if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.Camera) == (int)Permission.Granted) { // We have permission, go ahead and use the camera. } else { // Camera permission is not granted. If necessary display rationale & request. }
- ActivityCompat.ShouldShowRequestPermissionRationale method is used to determine if the rationale should be shown to the user
- If the user grants the permission, the ActivityCompat.RequestPermissions(Activity activity, string[] permissions, int requestCode) method should be called.
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults) { }
- Declare in manifest
- Drawable
- ShapeDrawable
- StateListDrawable
- LayerDrawable
- TransitionDrawable
- LevelListDrawable
- ScaleDrawable/ClipDrawable
- InsetDrawable
- BitmapDrawable
- Animation
- View Animations
- Property Animations
- ValueAnimator
- ValueAnimator.OfInt
- ValueAnimator.OfFloat
- ValueAnimator.OfObject
MyCustomObject myObj = new MyCustomObject(); myObj.SomeIntegerValue = -1; animator.Update += (object sender, ValueAnimator.AnimatorUpdateEventArgs e) => { int newValue = (int) e.Animation.AnimatedValue; // Apply this new value to the object being animated. myObj.SomeIntegerValue = newValue; };
- ObjectAnimator
MyCustomObject myObj = new MyCustomObject(); myObj.SomeIntegerValue = -1; ObjectAnimator animator = ObjectAnimator.OfFloat(myObj, "SomeIntegerValue", 0, 100); animator.SetDuration(1000); animator.Start();
- AnimationSet
- Evaluators used by animators
- IntEvaluator – Calculates values for integer properties.
- FloatEvaluator – Calculates values for float properties.
- ArgbEvaluator – Calculates values for colour properties.
- or implementing custom ITypeEvaluator
- ValueAnimator
-
Notifications
- User Interface
- Layouts
- LinearLayout
- RelativeLayout
- TableLayout
- RecyclerView
- ListView
- GridView
- GridLayout
- Tabbed Layouts
- Controls (Widgets)
- ActionBar
- AutoCompleteTextView
- Button
- Calendar
- CardView
- EditText
- Gallery
- Navigatin Bar
- Pickers
- Date
- Time
- PopupMenu
- RatingBar
- Spinner
- Switch
- TextureView
- ToolBar
- ViewPager
- With Views
- With Fragments
- WebView
- Layouts
Xamarin.iOS fundamentals
-
User Interface
- Controls
- Alerts
UIActionSheet
andUIAlertView
deprecated- Replaced with
UIAlertController
-
Use UIAlertControllerStyle to indicate the type of alert to display. These alerts types are:
UIAlertControllerStyleActionSheet
- Pre-iOS 8 this would have been a
UIActionSheet
- Pre-iOS 8 this would have been a
UIAlertControllerStyleAlert
- Pre-iOS 8 this would have been
UIAlertView
- Pre-iOS 8 this would have been
//Create Alert var okAlertController = UIAlertController.Create ("Title", "The message", UIAlertControllerStyle.Alert); //Add Action okCancelAlertController.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, alert => Console.WriteLine ("Okay was clicked"))); okCancelAlertController.AddAction(UIAlertAction.Create("Cancel", UIAlertActionStyle.Cancel, alert => Console.WriteLine ("Cancel was clicked"))); //required for iPad UIPopoverPresentationController presentationPopover = actionSheetAlert.PopoverPresentationController; if (presentationPopover!=null) { presentationPopover.SourceView = this.View; presentationPopover.PermittedArrowDirections = UIPopoverArrowDirection.Up; } // Present Alert PresentViewController (okAlertController, true, null);
- Buttons
- UIButton
- Set the button’s text. Use the SetTitle method, which requires the text and a UIControlState value for button state.
myButton.SetTitle("Hello, World!", UIControlState.Normal);
- The button’s state types are listed below:
- UIControlState.Normal
- UIControlState.Highlighted
- UIControlState.Disabled
- UIControlState.Selected
- UIControlState.Focused
- UIControlState.Application
- UIControlState.Reserved
- UIButton Types
- UIButtonType.System - A general-purpose button
- UIButtonType.DetailDisclosure - Indicates the availability of detailed information, usually about a specific item in a table
- UIButtonType.InfoDark - Indicates the availability of configuration information; dark-colored
- UIButtonType.InfoLight - Indicates the availability of configuration information; light-colored
- UIButtonType..AddContact - Indicates that a contact can be added
- UIButtonType.Custom - Customizable button
- Tap
myButton.TouchUpInside += (sender, e) => { DoSomething(); };
- Set the button’s text. Use the SetTitle method, which requires the text and a UIControlState value for button state.
- UIButton
- Collection Views
- UICollecionView
- Delegation and data source patterns
- UICollecionView
- Images
- Manual Camery Controls
- AVFoundation Framework
- Maps
- Map Kit
- Labels
- UILabel
- Pickers and Date Pickers
- Wheel like control
- UIPickerView subclass called UIDatePicker
- Progress and Activity Indicators
- Activity Indicators
- Progress Bars
- Sliders, Switches and Segmented Controls
- UISwitch
- Stack View
- UIStackView
- The Stack View control (UIStackView) leverages the power of Auto Layout and Size Classes to manage a stack of subviews, either horizontally or vertically, which dynamically responds to the orientation and screen size of the iOS device.
- UIStackView
- Tables and Cells
- Text Input
- UITextField
- UITextView
- Tab Bars and Tab Bar Controllers
- iOS applications using a tab-navigation UI are built using the UITabBarController
- WebViews
- SFSafariViewController
- Alerts
- Controls
text
public class SomeCSharpCode
{
}
<SomeXml>
</SomeXml>