Skip to main content

Change cursor and text selection with .NET MAUI on iOS

·4 mins

Earlier today I was looking at the .NET MAUI questions on Stack Overflow and saw this one. The question is: How to change the color of Editor cursor on Maui iOS?

To make sure even more people can benefit, I decided to write a blog post about it as well.

If you want to see a fully functional example, check the GitHub repository here: https://github.com/jfversluis/MauiCustomCursorColoriOSSample

.NET MAUI Handlers and Mappers #

As you might already know by now, the .NET MAUI architecture is based on handlers and mappers. Handlers basically describe a full control and mappers map each of the properties between the abstract (.NET MAUI) control and the platform control.

The .NET MAUI team makes their implementation of those handlers and mappers to do the magic, but not everything is implemented.

In this specific case, the cursor color and selection color is something that is supported on iOS, but not so much on macOS. I’m not sure about Android or Windows, but it is one of those small functionalities that has not been surfaced to the .NET MAUI APIs. Luckily for us, the mapper and handler architecture allows us to make tweaks like this easily!

You can read more about this architecture in the official Microsoft Docs.

Customize Controls with Mappers #

If you’re coming from Xamarin.Forms, you might know about custom renderers. And when I talk about custom renderers, you probably feel a chill going down your spine. They were not fun to work with.

Making tweaks like the cursor color in .NET MAUI is much easier. Note: there are multiple ways to structure your code depending on your taste. I will show you this one way which works well for one tweak, but if you need more tweaks like this your code might get cluttered. I leave it to you to find other and better ways to do it.

Official documentation on customizing controls is to be found on Microsoft Learn here.

Change the Entry Cursor Color in .NET MAUI for iOS #

Changing the cursor color is basically these 5 lines:

Microsoft.Maui.Handlers.EntryHandler.Mapper.AppendToMapping("CursorColor", (handler, view) =>
{
#if IOS
    handler.PlatformView.TintColor = UIKit.UIColor.Green;
#endif
});

Here are the things to note. First, EntryHandler.Mapper. As said: the handler represents the full (.NET MAUI) control and the mapper is a dictionary that maps each .NET MAUI property to the platform property.

You can easily extend that handler and mapper by using AppendToMapping. By using this method, you will let the .NET MAUI default implementation run first, and at the end your custom code, written here, will be added to add the final customization. There is also PrependToMapping or ModifyMapping which lets you add something before the default implementation runs or replace the entire default mapping that is in place.

Then inside the AppendToMapping you can see the compile directive #if IOS. Because we’re going to use iOS specific code here, we need to let the compile know that this only needs to be compiled when we’re building for iOS.

The actual implementation of the cursor color is just one line. Through the mapper we get the handler and from the handler we can access the platform control, in this case a UITextView. That iOS UITextView has an API to set the TintColor which determines the cursor color and we can simply set that to any color we like.

A screenshot of the running iOS app that shows an Entry control which has some text selected. The selected text and cursor has a green color.
The green cursor and text selection color in action

Change Entry Cursor Color for a Specific Control #

The code above will apply to all Entry controls. Maybe, you just want to apply it to one specific set of controls. In this case you can inherit from the control you’d like to customize and check for that.

When implemented, the resulting code would look like this:

// Add a new, custom Entry
class MyGreenEntry : Entry
{
}

Microsoft.Maui.Handlers.EntryHandler.Mapper.AppendToMapping("CursorColor", (handler, view) =>
{
#if IOS
    // Check the type first before applying
    if (view is MyGreenEntry)
    {
        handler.PlatformView.TintColor = UIKit.UIColor.Green;
    }
#endif
});

Where Do I Put This Code? #

In the sample repository I added it to the MauiProgram.cs. Since the handlers and mappers can be accessed staticly, you can basically do it everywhere.

This means you can put it in a separate class in your shared code or maybe under the Platforms folder so you don’t need the #if compiler directives. As long as the code is called somewhere before you start using the control, in this case, before you show your first Entry control.

In Closing #

You now know how the handlers and mappers work and how you can use them to tweak existing controls. The code for this can be found on my GitHub: https://github.com/jfversluis/MauiCustomCursorColoriOSSample

If you’re more into learning through video, you might also want to subscribe to my YouTube channel!