Xamarin Forms – iOS floating tabbar

Sometimes the design of our apps requires us to create custom elements inside of Xamarin Forms.
One thing I wanted to try out, was using a floating tabbar instead of a bottom fixed one.

The end result should be this:

Let me show you how you can achieve this in Xamarin Forms targeting iOS.

We actually don’t want to create our own page panel switcher or view host, rather, we would love to reuse the current TabbedPage that is provided by Xamarin Forms. So if we want to alter the one given by Xamarin, we need to create a Custom Renderer for it.
In this custom renderer we will be hide the default TabBar that is provided by iOS and instead we will load a Xamarin Forms ContentView and place it inside the UIView that is currently loaded; placing it somewhere on the bottom of the page.

Meaning we need to convert the ContentView to a iOS native control! This is possible all thanks to Michael Ridland his code shown here https://michaelridland.com/xamarin/creating-native-view-xamarin-forms-viewpage/

The end result Custom Renderer looks like this:

Now that our view is visible and the default tabbar is hidden, we only need to trigger the actual tab switching.
This is done inside our ContentView!
Inside of the new TabBar view, we have defined 3 buttons. Each button will trigger a page switch, doing this through use of the Xamarin Forms Tabbed Page. We just switch the CurrentPage property of the TabbedPage and this will trigger the normal tab switching.

That is basically it!
As you can see the overlay tabbar is just XAML, so you can do whatever you want in it… of you would like to animate the selection or use images, you can just change it.

The end effect is like so:

As always the code can be found on GitHub here…

Xamarin forms – Android label less bottom tabs with badges

Since a while we are able to render a bottom tabbar in Xamarin Forms for Android!
If you want to know the whole setup, take a look at this great blog post by James Montemagno here…

So recently we added this in our production app, because our own implementation was not always working 100% correct depending on the Android version it was being shown.

But we also needed some extra functionality and didn’t want to bring in an external library. So let me show you what we needed and how we added this to Xamarin Forms Android.

First extra needed feature was the ability to show tab badges. In other words a counter that shows, in our case, the amount of unread messages.
End result should be:

Now the fact that we eventually also need to port this to iOS, means we need some abstracted elements that reside in Xamarin Forms project and not in the os specific projects.
First we need a small class that can contain the badge info that we want to show, it has 2 properties, one for the badge caption and one for the badge color.

So when you want to dynamically change the color or caption, you just change the data in the properties and the code on os level will handle this.
Because we want to interact on os level, we need to create a Custom Renderer. To be sure it can get a hold of the TabData class we also create our own TabbedPage first.

I pre-init this page with a badge for the first tab that is blue and has 5 as caption.
With that in place we can start adding our Android Custom renderer.

The actual end goal of the custom renderer is to inject a badge control in each tab where needed. So we have to go through the Tabs dictionary of the BottomTabbedPage to see if we need to add a badge or not. Also we want to hook into the PropertyChanged event of the BadgeData class, so that we can actually change the visuals while the app is running.
This is all handled in the OnElementChanged method of the Custom Renderer.

A bunch of code, but it’s not that difficult to understand… first we adjust the Shift Mode so that our tabs are always shown equally ( reference the blog post of James on top ).
After that we go through the defined TabData elements and get the corresponding BottomNavigationItemView ( the actual item being rendered ).

Note that in my example, I only have a badge on the first tab. When you want badges on each, you need to pre init the TabData list for each tab.

When we want to add a badge, we create a new TextView element and add it to the corresponding BottomNavigationItemView. The TextView itself is just text but with a circular background element ShapeDrawable, that inherits the color you specified in the BadgeData.
All this code can be seen in the BadgeView class.

Also note that we keep track of the PropertyChanged event, so that we alter the color and caption if needed of the presented BadgeView.
And that’s it for our first feature! Bottom tabs with badges for Android.

But we also wanted to have the ability to show only icons on the tabs, so loosing the labels. This will of course only work when you have very descriptive icons.
This should look like so:

Now normally this should be very easy in Android API 28, because there you can provide a value stating if you want labels or not… but since of this writing Xamarin Forms is not yet 28 compatible ( https://github.com/xamarin/Xamarin.Forms/issues/3083 ) so we need our own implementation.

For this to work, we will strip out the labels that are available in the TabView. But that is not enough, we also need to shift down the icon. Because when you loose the labels, the icon will not be in the center of the TabView. On our BottomTabbedPage class we already added a bool property Labels that we can set in XAML to indicate if we want tabs with or without labels.

In the OnElementChanged we strip out the labels.

And in the OnLayout we shift down the icons ( we only have the tab height at that point ).

So we take the actual height of the tab itself, divided by 2 to get the center. Than we grab the height of the icon and also divide this by 2 and also get the current top position of the icon. With those values we now know how much pixels we need to add as top padding to our icon to get it vertically center.

All in all not that much code, but as always with android, you need to know how the actual objects are called and rendered.

As always working copy can be found here…

Xamarin forms – keep visual element in view linked to content scroll view

Assume you have some news page that contains a header with the actual news title, some highlight image and a lot of body text.
If this is represented on a mobile device, depending on the screen resolution, this can result in the user needing to scroll the text content to be able to read everything.
Now if you just put the whole page in a ScrollView, the user will loose the content of the article he is reading, because most likely the title will also scroll out of view.
So let me show you what you can do to keep the title fixed as soon as it reaches a certain anchor point on screen, while the user is scrolling the text content.

The starting view looks like this

You will notice the title “Bear found in the wild” is fixed to the bottom of the highlight picture and as soon as the user scrolls, this will also scroll to the top of the screen. But we want to keep it in view when it reaches the top of the image ( it will be fixed below the “Fixed header demo page title ). even if the user keeps scrolling down after we reached our anchor point.

First the design of the page in XAML:

Import thing to note here, is that the actual TitleText label is positioned outside of the ScrollView! This is needed, because we will animate it ourselves depending on the scroll values of the ScrollView.
So how do we position this TitleText to the bottom of the bear image? This is done in the code behind of the page! In the constructor we hookup to the SizeChanged event of the bear image and in that event we will set the margin of the TitleText to the Height of the bear image minus the height of the TitleText itself.

Now when the TitleText has been fixed to it’s starting position, we need to take hold of the top Y coördinate. This is needed to calculate the anchor point while scrolling.
We also hookup to the SizeChanged event of the TitleText and when it changes, we can grab the Y point.

Only one thing left to do, we now have to keep hold of the scroll values of the ScrollView, so we can animate the TitleText in sync with the scroll position and direction.
So we subscribe to the PropertyChanged event of the ScrollView and look for Y value changes.
When we get a change, we validate if it is still lower than our anchor point, if so, animate the TitleText Y coördinate to the same value. If it’s passed the anchor point, we will just keep the TitleText coördinate the same. This will result in the title being kept in view!

And that’s it!
The end result will look like this:

As always a complete demo can be found on my GitHub here…

.Net Standard 2.0 create Microsoft Office documents in Xamarin Forms

We had to wait a while for it to happen, but it’s finally here; .Net Standard 2.0 support in Xamarin Forms.
This is a big step in sharing .net code across multiple platforms while able to target a wide range of APIs.

To show of the power of this, let’s do a fun example.
Wouldn’t it be nice if you could create Microsoft Office Excel of Word files on the fly inside your Xamarin Forms app? Of course you could offload this to a backend service, but that means you also need to be the owner of the data service. On the other hand creating simple CSV files that are compatible with Excel is also a possibility, but you are limited to only adding data in that case ( no formula’s or formatting ).

Thanks to .Net Standard 2.0 we can now use the full Office OpenXML SDK inside our Xamarin Forms apps!

First things first, how do we create a Xamarin Forms app with a .Net Standard 2.0 lib instead of a PCL.
To accomplish this now ( without any new Visual Studio templates ), just create a new blank PCL Xamarin Forms app.
When this is done, add an extra project but this time select a .Net Standard Library. You’ll get a popup window for selecting which version of .Net Standard you want to target, select Version 2.0!

If you don’t see version 2.0 yet, that means that you still need to install the new .Net Core 2.0 SDK. For using it on a Mac goto https://www.microsoft.com/net/core#macos.

When the project is inside your solution, first delete the class1 file and add the Xamarin Forms nuget package ( at least v 2.4.* ) and when that is done, just drag and drop the PCL files over to your new .Net Standard library.
Now you can just delete the old PCL project.
Reference the .Net Standard lib in your iOS and Droid projects and you are good to go.
For our example we also need to add the OpenXML nuget package so that we create and manipulate Docx and Xlsx files.

Let’s assume you have some data in a local database of pulled down from a REST service, it’s nicely presented on your screen and you can annotate and filter it.
When you are done you want to transfer this set over to some coworker but he is working in another environment and excel would suit better.

So how do we create an Excel file with this data blob?
Let me show you the code

The key element from the OpenXML SDK is the SpreadsheetDocument class, this allows us to generate a new empty Excel file! After that it’s only a matter of adding a new sheet and giving it a name.

When this is done, we still need to add data… this can be accomplished with following code

I’ve created a separate method for inserting data into an existing Excel file ( in our case the one we just created with the code previously shown ).
This method uses a class called ExcelData it’s nothing more than a simple POCO with string lists… one for the headers and the rest for the data.

Once the data is passed to the method, we’ll open up the first Worksheet available in our Excel file and inject data rows. Each row will get a set of Cells, in which we put our string data.
In this example I made it very straightforward and didn’t do any fancy Excel stuff… but now you have the basics of how to handle OpenXML files! If you go through the SDK docs, you’ll see that there is a lot more available.

Now that we have our filled up spreadsheet, we want to be able to share it. This can be done through platform specific code… for iOS we need to use a UIDocumentInteractionController

When this is used, you’ll be presented with an Open with popup where you can select different applications that are installed on your mobile device.
If Excel is installed you can actually see the generated file!

The code is available on my GitHub here…

Xamarin Forms – RepeaterView

Back in the day there was this great open source lib called XLabs that targeted Xamarin Forms.
It had a lot of nifty controls and custom renderers to fix several pain points while developing for Xamarin Forms.
But Xamarin Forms evolved and XLabs was not maintained as regular anymore and it now seems to be stranded at a dead end.

BUT, even though the code targets an older version of Xamarin forms, it doesn’t mean that there is no longer any value in it.
I’ll give you an example: the RepeaterView.

This is a nice control that helps you ‘repeat’ data elements without actually using a ListView, this can be handy if you just want to show an iteration without any possible user interaction, or if you want to be able to show all items in the collection and control your own scroll region.

Whatever the reason, XLabs had us covered and we can still use it today!

So let me show you an example of how I needed to use it on a recent design issue I had.
I needed to present data grouped, but in 3 levels. Meaning, we have a bunch of payment transfers and they are grouped in ‘signed’ and ‘unsigned’ groups, but inside those main level groups we again need to group the transfers per user account. With each account listing the transfer items with their details…

In short, this would not be doable straight out of the box wit general ListView grouping. You could just put 2 ListViews on the page, but that would not help the UI. Because we want the user to be able to scroll through 1 list with all the data in it.

There are possibly several ways of fixing this, but I went for the use of RepeaterView in combination with a grouped ListView.

First let me show you what we are going to build ( don’t judge the layout 😉 )

To achieve this we need following models

Transaction and Account class, are the real data holders and we added GroupedTransaction and GroupedAccount to be able to actually group the data and use it for the grouped ListView.

Next up the RepeaterView, I modified the XLabs version so it would work in our newer Xamarin Forms environment, but do note that my version is also stripped down to the bare minimum that I needed for this UI.

The RepeaterView takes a generic T that is being used for the items enumerator. We need to keep that in mind when we write our XAML, because this has to be supplied there.
Other than that this control is very basic, you need to give it an ItemsSource and an ItemTemplate and it will use those to build the UI.
There is also an extra option to add a HeaderTemplate, if you want some text on top. But this isn’t used in this demo.

For the actual UI we need following XAML

We are using a grouped ListView for creating the first and second data level, in our case the signed and unsigned transactions are mapped with the ListView GroupHeader, the account information is used in the ItemTemplate.
But also inside of the ItemTemplate we are using our RepeaterView to show the transactions.
This will give use 3 levels of information that are all repeatable.
Note the use of x:TypeArguments=”models:Transaction” on the RepeaterView, that’s the way to pass data to your model. This will be used for the type T of the RepeaterView.

As always a complete demo can be found on my GitHub here…

Xamarin forms – Clear entry control effect

When using the Entry control of Xamarin forms, we don’t have a standard fast way to let the user clear his typed in text.

It would be nice if we could add a Clear icon on the right side of the entry control that clears the current text when tapped.
Example Android and iOS:

Android previewiOS preview

Let me show you how this can be done with an Effect for Xamarin forms!

Do read up on how to create effects in Xamarin forms here…

First iOS, because this is actually the easiest to implement.
In your iOS project add a folder called Effects and in it add a new class file called ClearEntryEffect.cs.
The code for this file is as follows

In this effect, we just get hold of the UITextField native control of the Entry and adjust the ClearButtonMode property to UITextFieldViewMode.WhileEditing. This is possible due to the fact that the iOS UITextField actually has this feature build in, we only need to trigger it.
So one down, one more to go…

Android is a bit trickier, because the native EditText control does not have this pre build in, in other words we need to add this ourselves.
Again add an Effects folder, but now in the Android project and again add a ClearEntryEffect.cs class file.
The code for this one looks like

The code is not all that different, we just need to add some extra tweaking…
First, we add a Clear icon on the right side of the EditText control, this can be done with the editText.SetCompoundDrawablesRelativeWithIntrinsicBounds method on the EditText control.
You add a correct resource id to the correct position, we want it to the right hand side, so it needs to be the third parameter.
Secondly we are going to add a touch listener to the EditText control, using the SetOnTouchListener method.
In this touch listener, we verify if the EditText control is being tapped, MotionEventActions.Up, if so we verify what the actual position was where the user has tapped. If this location is anywhere inside the region of the right drawable, we clear the text of the EditText control.
You get the actual position from the touch event through the event arguments, e.RawX and we calculate the position of the drawable and compare these two values: e.RawX >= (editText.Right – editText.GetCompoundDrawables()[2].Bounds.Width())

So that wasn’t that hard, only needed to read up a bit on Android because I’m still a novice on this one.

After adding these 2 effects, only thing left to do is use them in your Xamarin forms pages!
Thing to remember here is that you still have to create a dummy class in the PCL as well… so add a class file called ClearEntryEffect.cs inside the PCL with following code

And when this is all done, you can use it in your xaml as follows

As always everything can be found on my GitHub here…

Xamarin forms – iOS disable cancel button on SearchBar

When you are using Xamarin forms and add the SearchBar control, you’ll notice that there will be a Cancel button shown while you are typing text in the search entry area.

We wanted to get rid of this cancel button, to get a cleaner design…
So I looked for the iOS reference on the UISearchBar and it seems that by manipulating the ShowsCancelButton property, you can show or hide that button.

To get this working I did what any Xamarin dev would do when you need to tweak native properties that are not available in Xamarin forms itself, I created a Custom renderer for the SearchBar…

The code is fairly simpel:

BUT when trying this out in a demo app, I noticed that the Cancel button would still appear when I started typing text in the search entry!!
No idea why this could be happening, I opened the Open Source code of Xamarin forms to take a look at how the guys of Xamarin are handeling the SearchBar.

And yes, thank god it’s Open Source, because now I could see why my custom renderer has no effect!
If we take a look at https://github.com/xamarin/Xamarin.Forms/blob/74cb5c4a97dcb123eb471f6b1dffa1267d0305aa/Xamarin.Forms.Platform.iOS/Renderers/SearchBarRenderer.cs#L167, we can see that the Xamarin forms base SearchBar renderer for iOS will toggle the ShowCancelButton property as soon as you change the text of the search entry… In other words, this will override my initial setting in my custom renderer.

Back to square one, how can we still hide the cancel button in this scenario?
Well if you look further in the code of Xamarin Forms, we will see that the cancel button is being updated each time the TextProperty and the CancelButtonColor property are changed.
So we need to override that behavior instead…

To do this, we’ll change our custom renderer and only add following code:

By adding this code we will bypass the base code of OnElementPropertyChanged if one of these 2 properties change. We do still copy/paste the original Xamarin forms code for the TextProperty because this is needed.
I did not however, copy over the code for the color changing of the cancel button – because want to hide it, so no need for that code in our project!

Well still not sure why the guys at Xamarin are forcing this cancel button, but great to know the code is Open Source so we can at least act upon it 🙂

Final result ( first one is the faulty renderer, second one is the correct renderer )

screen-shot-2016-10-27-at-14-51-15

All the code up on my GitHub

UWP – Split view deep dive ( the story of desktop mode or mobile mode )

So by now most people will know that I’m ‘still’ busy creating a Strava app for UWP called Kliva ( yes it is Open Source here… ).
Now the main purpose for using UWP was the fact that we could create 1 app that can be used on desktop/tablet pc’s and mobile phones!
Thanks to the new way of using Visual States in XAML we can tweak our design like we want depending on the size of the screen real estate.

All fine and dandy, but depending on the form factor it could also be that we need to navigate in a different way, Microsoft illustrated this by defining a Stacked Pattern and a Side-by-side pattern.
Read up on all the details here…

Now how can we as devs handle this difference in navigation? Well let me show you how we handled it in Kliva.

First we defined our own ApplicationFrame ( inherits from Frame ).

You’ll notice we do 2 things here, enable a Loading mode if needed and when a page is Navigated we trigger some code in a ViewModel.
Let’s deconstuct this later, I’ll first show you the actual frame setup…

So our frame will always consist of a SplitView control and the actual pages of our app will be rendered inside the SplitView.Content part!
We are using the SplitView control for the Side-by-side pattern reason, we will however need to adjust this in mobile mode, again more on this later 🙂 ( yep going to be a long post )

More importantly, we are now able to sneak in a full app wide loading overlay control. In other words, each time when needed, we will present an overlay with a progress ring, to indicate the app is still processing. By putting it here, inside the boilerplate code of the ApplicationFrame, it is available for all pages in the app!
Remember the code in the KlivaApplicationFrame? There is a method called ShowLoading(bool isLoading), this will put the Loading Grid in the correct VisualState ensuring it is visible or not and will also trigger the progress ring ( inside the LoadingControl ) to start.
The loading control itself is a user control that is nothing more than some text and a progress ring as show below…

But the real magic is in it’s code behind

We added the IsLoading property, so we can access it in our XAML – like we do in the VisualStates of the KlivaApplicationFrame.
But we also added a static method SetLoading(bool isLoading), we need this so that we can trigger the whole process of actually showing the control to the user!
In Kliva we let all our ViewModels inherit from a BaseViewModel and inside this one, we will call upon this static SetLoading method each time we think our app will need some time processing web requests.

So from a developer standpoint, each time you manipulate the IsBusy propety on the base viewmodel, our Loading Control will be shown to the user.
If you don’t like the ‘link’ between the ViewModel and the actual control, you could also work with MVVM messaging instead. No need for a static method that way, but hey we can’t always be 100% MVVM, right? 😉

Back to solving the mobile view, because you’ll remember that our original setup uses a SplitView and on mobile we want to shift this to actually using a BottomAppBar. To achieve this we need 2 things, hide the SplitView.Pane and showing the BottomAppBar.
Showing the bottom app bar is not that hard! We just check for the correct view size in our VisualStates and if needed toggle it’s visibility property depending on how large the screen actually is. From 320 to 720 we show it, everything above 720, we hide it.

Hiding the SplitView.Pane will need some coding… First part of this was already shown in our KlivaApplicationFrame, there when we navigate to a page we call upon the ShowHide method of the SidePaneViewModel.
This ViewModel is linked to the SidePane Control that is used inside the SplitView.Pane. We use several properties of this viewmodel on our SplitView properties, like the DisplayMode and IsPaneOpen ( cfr XAML code of our KlivaApplicationFrame ).
When we don’t need the SidePane of our SplitView, we set the DisplayMode to Inline and IsPaneOpen to false, if we do need the SidePane, we put the DisplayMode into CompactOverlay. That way, if on mobile, we can hide it and on desktop show it again.
We also extended the method a bit, so that we can hide the side pane on a given type of page, if needed ( currently not used )

Last but not least, we still need to find a way to adjust for page navigation or not. In our case, our main page will show a list of activities and when selecting one, present the details of that activity.
In a side-by-side pattern the details of the activity is on the right side of the list, in a stack pattern we need to navigate to the details page.

The side-by-side way is very easy, we put 2 controls in our main page, the first one contains the lists, the second one the detail info. Each of these controls are bound to the same ViewModel. So when an user selects an item from the list we will fill in the SelectedItem property on our ViewModel and our detail control will automatically show this.
But for the stacked pattern we add a bit of extra code, first again thanks to use of the VisualStates we will hide the detail control and secondly in our SelectedItem invocation we will try to start a page navigation if we are on mobile.
Not rocket science, just a little tweaking 🙂

The complete detail code for this can be seen on our github page for Kliva right here…

UWP TitleBar – inactive color

Just a small tip for desktop UWP apps!
I needed to look this up and it took me more time than I thought it would… so blogging it for reference 🙂

If you create an UWP app, you’ll notice that the app title bar will change color depending on the fact it has or has not the focus.

This can be useful, but if you already themed your app and took time to style the titlebar with some color, it just looks weird the color is no longer the same when not in focus.

So what do you need to do to get the app title bar stay the same, here is the code:

You first check if we are running in desktop mode, if so we get a hold of the titlebar and when you have that, just set Inactive*** properties the same as the normal ones!
That’s it…

Happy coding

Xamarin forms – iOS pin entry control

** Update : there is now also a new property ClearText that will show what you entered if needed

Most apps will have some kind of login feature, passing in credentials. Often this will be done with an Entry control set IsPassword to true.

But for a project we are working on, we needed a pin code entry… In other words, let the user see how many digits he has to enter and only allow numeric values.

So something like this:

PinEntry

To accomplish this, we created our own control. It’s a grid that will draw columns for the amount you’ve assigned to the PinLength property and it will add small dots and big dots. The big dots will become visible when the user enters digits.
Some other nice properties, you are able to hook up a Command that will be fired when the user has entered all required digits, this can be used to verify the pin.
The value of the pin is available in through the Input property.
There is also a Reset method to clear the input and redraw all small dots.

Example XAML usage:

For now I’ve only added the iOS implementation, this because there is currently no easy way to auto show the keyboard on Android. But a work around is to draw your own keyboard on screen and hook up the Input property of the Pin control.

All code and sample page can be found on my GitHub here…

Anyhow, hope this can be of any use!