Adjusting font Size of Xamarin’s Picker (Part 2)

I already made 2 post about picker, but in this post I want to be more specific about picker in iOS especially about it’s text size. I already told how to do it in Android, now it’s iOS’s turn.  First thing first, now let’s review the custom picker class.

Custom Picker Class

This class actually is almost the same with class in my older post. The only thing I did is changing the name of FontSize property into TextSize. This is because I got warning saying that Font Size is hidden property that Picker already had. I didn’t get this warning when first time I created this class, so I made little adjustment here.

public class CustomPicker : Picker
{
    public static readonly BindableProperty TextSizeProperty =
        BindableProperty.Create(nameof(TextSize), typeof(float), typeof(CustomPicker), 24, BindingMode.TwoWay);

    public float TextSize
    {
        set { SetValue(TextSizeProperty, value); }
        get { return (Int32)GetValue(TextSizeProperty); }
    }

    public static BindableProperty PlaceholderColorProperty =
        BindableProperty.Create(nameof(PlaceholderColor), typeof(string), typeof(CustomPicker), DefaultColor, BindingMode.TwoWay);

    public string PlaceholderColor
    {
        get { return (string)GetValue(PlaceholderColorProperty); }
        set { SetValue(PlaceholderColorProperty, value); }
    }

    public static string DefaultColor => "#CCCCCC";
}

Picker iOS Renderer

Now let’s move on to the picker renderer in iOS project. This class also similar with a class with same name in my old post, when I discussed about placeholder color. The only difference is I added some lines of code to adjust it’s text size. And it’s actually a little bit tricky to do that.

To change the size of picker’s text in iOS, we need to create something called FontDescriptor. Ok, I’m not expert on swift programming, and maybe there’s better way to create FontDescriptor, but I did it by taking the descriptor of UILabel’s font. After I got the description, I made new Font descriptor from it with adjusted size property. Then I create new UIFont with that new description.

Lastly, I put my new font to NSAttributedString so I can update the AttributedPlaceholder and AttributedText property of the iOS picker. I did it so the placeholder and the text had same set of attributes.

public class CustomPickerRenderer: PickerRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs e)
    {
        base.OnElementChanged(e);
        if (e.NewElement != null)
        {
            var customPicker = e.NewElement as CustomPicker;

            // get Bindable properties
            UIColor placeholderColor = GetUIColor(customPicker.PlaceholderColor);
            float textSize = (float)customPicker.TextSize;

            // create font decsriptor
            var label = new UILabel();
            var fontDescriptor = label.Font.FontDescriptor;

            // adjusting font size
            var newDescriptor = fontDescriptor.CreateWithAttributes(new UIFontAttributes()
            {
                Size = textSize
            });
            UIFont font = UIFont.FromDescriptor(newDescriptor, 0);

            // set attributes
            var placeholderAttributes = new NSAttributedString(customPicker.Title, new UIStringAttributes()
            { ForegroundColor = placeholderColor, Font = font });

            Control.AttributedPlaceholder = placeholderAttributes;

            var textAttributes = new NSAttributedString(customPicker.Title, new UIStringAttributes()
            { ForegroundColor = placeholderColor, Font = font });

            Control.AttributedText = textAttributes;<span id="mce_SELREST_start" style="overflow:hidden;line-height:0;"></span>
        }
    }

    private UIColor GetUIColor(string color)
    {
        return UIColor.FromRGB(GetRed(color), GetGreen(color), GetBlue(color));
    }

    private float GetRed(string color)
    {
        Color c = Color.FromHex(color);
        return (float)c.R;
    }

    private float GetGreen(string color)
    {
        Color c = Color.FromHex(color);
        return (float)c.G;
    }

    private float GetBlue(string color)
    {
        Color c = Color.FromHex(color);
        return (float)c.B;
    }
}

 

Sample Code is available in my Github repo

Github Announcement

Some of you guys have asked me to put sample code on Git. So, today is the day, I’ve created a Github account and and put some of the sample code in a repository there. You can access my repo in this link. Until I created this post, I already added 2 sample code, but I will add more code soon in the future. Here’s the sneak peak of the sample code.