A quick post to describe how to build a Xamarin iOS project from MSBuild on a Windows machine. You still need a mac available but this approach means you can create an iOS artefact from a Windows TFS build agent.
Here’s a walkthrough interface for use in Xamarin Forms apps. With a some work it’s easy to move beyond the default layouts and navigations patterns and make something a bit more exciting.
The video shows it in action. You can switch between pages using the buttons or by swiping. The content for the walkthrough control is defined by a list of views; it can be anything you want. The page indicators update every time you change a page.
The view provides properties to adjust the background color, back and next text, the image used for the progress indicators, and the amount of padding used for the control area.
If you want to know how it works you can dive into the source here. In this post I’ll just run through the key parts.
The content view XAML is just a stack layout which contains two grids. The top grid expands to fill the screen and contains the child content pages when they are added. The bottom grid contains the controls to switch the page. There’s also a gesture recognizer on the whole view to pick up swipe gestures.
The key bit of code for the content view is the SetContent method. This takes a list of views and adds them into the grid. It offsets the children at intervals of a page width – so initially they extend horizontally out to right of the screen. When the page changes it animates each of the children to shift them right or left. The other thing it does is expose the configurable options.
I’ve split a lot of the logic for which pages andbuttons are displayed out into the WalkthroughController class for a couple of reasons. Firstly it’s easier to write unit tests, and secondly it nicely separates the processing and interaction logic.
That’s pretty much it – a bit of XAML and a couple of simple classes produce a nice, configurable interface 🙂
Here’s a quick demo and explanation of a repeater view I made for Xamarin Forms. It simply repeats a set of controls for a collection of items that it’s bound to. A ListView does this too but isn’t always what I want. It’s surprising something like this isn’t included in the framework but making your own is fairly simple.
Source code and a sample application are available here.
Here’s what it looks like in action. In this simple demo each item is represented by a Frame that contains a label and a button.
Let’s look at some key points in the code. The view is based on StackLayout which will take care of positioning the items.
public class Repeater : StackLayout
There are a couple of bindable properties – ItemTemplate for the item layout and ItemsSource which provides the items. Note that ItemsSource hooks an action to PropertyChanging – I’ll come back to this later on.
The Populate method clears out the layout, then populates the template for each item and adds it in.
public void Populate()
if (this.ItemsSource != null)
foreach (var item in this.ItemsSource)
var content = this.ItemTemplate.CreateContent();
var viewCell = content as ViewCell;
if (viewCell != null)
viewCell.BindingContext = item;
If we just wanted to bind to an IEnumerable we wouldn’t need anything more. However when binding to an ObservableCollection the list wouldn’t update when items are added or removed. ObservableCollection fires OnCollectionChanged, not OnPropertyChanged, when the list is updated. This is where the ItemsSourceChanging method we hooked up in the binding is used.
When the ItemsSource is changing we check to see if it implements INotifyCollectionChanged, if so we subscribe to the OnCollectionChanged event and populate the list when it fires. We also need to make sure we unsubscribe if the items source changes.
So that’s it, a simple alternative to ListView for repeating a set of controls.
Here’s a weird macOS issue I’ve just run into while doing some cross platform development with Xamarin. If you have a folder which has a dot in it’s name it finder will sometimes think it’s a file. For me this was when the name ended in .workflow…
This happens when the element after the last dot is recognised as a file extension. After some head scratching I found an easy solution – right click on the folder and select ‘Show Package Contents’
Xamarin Forms is missing a flow layout control so I made one! It’s available here. It lays out child views from right to left, and moves on to a new row when it runs out of space.
Here’s a screenshot of a demo app…
This is the first layout I’ve made and I was surprised how easy it was. Layouts are written in the cross platform code; there isn’t a platform specific element.
To create a layout you create a new class that inherits from Layout…
public class FlowLayout : Layout<View>
The override the LayoutChildren and OnMeasure methods…
protected override void LayoutChildren(double x, double y, double width, double height)
var layoutInfo = new LayoutInfo(Spacing);
for (int i = 0; i < layoutInfo.Bounds.Count; i++)
var bounds = layoutInfo.Bounds[i];
bounds.Left += x;
bounds.Top += y;
protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint)
var layoutInfo = new LayoutInfo(Spacing);
return new SizeRequest(new Size(widthConstraint, layoutInfo.HeightRequest));
I chose to use another class – LayoutInfo – to handle the layout. This meant I was able to easily write unit tests. Trying to unit test the actual layout class is difficult as it needs the Xamarin Forms framework to work in the test environment.
In this post I discuss a solution for creating a consistent version number across .net, Android, and iOS for Xamarin cross platform apps. I also list a couple of powershell scripts which help with setting the versions
.net, Android, and iOS, all use different systems for versioning. When developing cross platform apps we consistency of numbering across the different platforms.
.net Version Numbers
.net Version numbers use a four part version number with the format <major version>.<minor version>.<build number>.<revision>
Often you’ll see version numbers with asterisks – 1.0.* or 1.0.. – When these are used the build number the build number increments every day and the revision number is random. .net version numbers are stored in the AssemblyInfo file for a project.
Android Version Numbers
Two numbers are used in Android versioning – the versionCode is an integer with higher numbers indicating more recent versions. It’s never shown to users. The versionName is a string which is displayed to users and can be anything you want. These numbers are stored in the AndroidManifest.xml file.
iOS Version Numbers
An iOS app has two version numbers which work together – A Version Number (CFBundleShotVersionString) and a Build Number (CFBundleVersion). The Version number identifies a release, and for each release the build number increments for each build that is submitted to the store. These numbers are stored in the Info.plist file.
‘Common’ Version Numbers
For Xamarin applications we want consistency of version numbers across the platform specific versions of an app, and it makes sense to use the .net version number as the ‘master’.
We can either use the automatic numbers as described above, or, if using TFS/VSTS use a number in a format such as 1.2.$(DayOfYear)$(Rev:.rr) and update the assemblyinfo
For example lets say the .net version number is 126.96.36.199.
This powershell script will update all the assemblyinfo files in a solution.
For Android the versionName, which is just for display, can be set to the full four part version number from .net. The versionCode just needs to increase from the previous version. Here's a script which takes the global build number from TFS, but could be easily modified to increment the existing number.
With the example version number this would give us a versionName – 188.8.131.52 – and a versionCode which is unique incremented number.
# Sets version in an Android manifest.
# The version name is set to the specified value.
# The version code is set to the build number from TFS.
Write-Output "Setting Android Version"
Write-Output "Version: $version"
Write-Output "Manifest: $manifestPath"
$xml = [xml](Get-Content $manifestPath)
$manifestNode = $xml.manifest
$versionCodeNew = $env:BUILD_BUILDID # This is the global build number from tfs - it increments with every build of every project.
$manifestNode.Attributes["android:versionCode"].Value = $versionCodeNew
$manifestNode.Attributes["android:versionName"].Value = $version
Write-Output "Manifest Updated"
For iOS we can split the four part version number. The first three parts can be used for the version number and the last part can be used for the build number. Here's a script for that. From the example version number this gives us a version number – 1.4.102 – and a build number – 13.