Ione Souza Junior

Como customizar cor do UINavigationBar e UIAlertController no Xamarin.iOS

12/07/2017 | 8 minutos de leitura | Tradu√ß√Ķes: en | #xamarin #ios

Fala galera, beleza? J√° faz um tempo que queria escrever aqui no blog. Felizmente, hoje tive a oportunidade de compartilhar com voc√™s mais uma coisa que aprendi nos √ļltimos dias. Este post fala sobre como customizar os estilos de alguns elementos de UI no Xamarin.iOS em apps desenvolvidos com Xamarin.Forms. Vamos l√°!

Para exemplificar, criei um novo app com Xamarin.Forms. Nele, adicionei uma p√°gina de in√≠cio com uma barra de navega√ß√£o e inseri dois bot√Ķes no corpo da p√°gina e mais um bot√£o na barra de navega√ß√£o, e obti este maravilhoso resultado compilando no iOS:

Navigation bar com cor padr√£o
Navigation bar com cor padr√£o

Lindo né? Então experimente mostrar isso para alguém que espera que o aplicativo seja bonito. Provavelmente será um desastre! Qual será o próximo passo então? Acertou quem disse customizar as cores. Mas como fazer? A maneira mais simples e mais rápida é adicionar um style nos resources do nosso projeto compartilhado e customizar a cor de fundo da barra de navegação e a cor da letra da mesma. O arquivo que estamos falando é o App.xaml. Customizamos da seguinte maneira:

<?xml version="1.0" encoding="utf-8"?>
<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Core.App">
    <Application.Resources>
        <ResourceDictionary>
            <Color x:Key="MainColor">#48bb6f</Color>
            <Color x:Key="MainBarTextColor">White</Color>

            <Style TargetType="NavigationPage">
                <Setter Property="BarBackgroundColor" Value="{StaticResource MainColor}" />
                <Setter Property="BarTextColor" Value="{StaticResource MainBarTextColor}" />
            </Style>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Como resultado, temos:

Navigation bar com cor customizada
Navigation bar com cor customizada

Nossa! J√° sou designer! rsrs Por√©m, ainda existem aqueles bot√Ķes que continuam com o estilo padr√£o do iOS, em azul. Vamos customiza-los tamb√©m, apenas adicionando mais um estilo aos resources:

<?xml version="1.0" encoding="utf-8"?>
<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Core.App">
    <Application.Resources>
        <ResourceDictionary>
            <Color x:Key="MainColor">#48bb6f</Color>
            <Color x:Key="MainBarTextColor">White</Color>

            <Style TargetType="NavigationPage">
                <Setter Property="BarBackgroundColor" Value="{StaticResource MainColor}" />
                <Setter Property="BarTextColor" Value="{StaticResource MainBarTextColor}" />
            </Style>

            <Style TargetType="Button">
                <Setter Property="TextColor" Value="{StaticResource MainColor}" />
            </Style>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Agora sim, bem melhor…

Bot√Ķes da tela com cor customizada
Bot√Ķes da tela com cor customizada

Agora voc√™ sai animado com seu app ‚Äútodo estilizado‚ÄĚ e vai implementar um bot√£o que deve fazer uma pergunta ao usu√°rio. Ent√£o, ap√≥s implementar vamos testar e‚Ķ

Dialog exibido com bot√Ķes na cor padr√£o
Dialog exibido com bot√Ķes na cor padr√£o

Olha o botão azul, padrão, novamente… Dai a pessoa fala:

...mas eu alterei a cor dos bot√Ķes, eu juro...

A pessoa programadora não está errada, porém, acontece que este botão pertence ao UIAlertController e está fora do alcance da estilização do Button, que realizamos lá nos styles do Xamarin.Forms. E agora? Calma, devemos fazer uma customização lá no Xamarin.iOS, assim teremos o resultado que desejamos. Legal, mas como faz?

No AppDelegate.css iremos criar um novo m√©todo para definir nossos estilos personalizados, que chamei de BuildStyles neste projeto de exemplo. Como j√° havia definido as cores padr√Ķes nos resources l√° do projeto compartilhado, carreguei estes resources e as cores definidas e converti o Color do Xamarin.Forms em UIColor do iOS, ent√£o apliquei o estilo a um determinado objeto do UIKit.

Como o componente que queremos estilizar é o UIAlertController, inicialmente procurei a propriedade Appearance neste objeto, mas sem sucesso. Só depois descobri que o objeto UIView seria o responsável por fazer essa estilização, não somente no UIAlertController, mas também em outros elementos de UI do iOS. No final, chamei o método para carregar os estilos no FinishedLaunching após a chamada do Xamarin.Forms, pois o método de estilos chama os resources do Xamarin.Forms, fique ligado nisso.

using Foundation;
using UIKit;
using System;

public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
    public override bool FinishedLaunching(UIApplication app, NSDictionary options)
    {
        global::Xamarin.Forms.Forms.Init();

        LoadApplication(new App());
        BuildStyles();

        return base.FinishedLaunching(app, options);
    }

    private void BuildStyles()
    {
        var xfResources = Xamarin.Forms.Application.Current.Resources;
        if (xfResources == null)
            return;

        var mainColor = "MainColor";
        var mainBarTextColor = "MainBarTextColor";

        if (!xfResources.ContainsKey(mainColor) || !xfResources.ContainsKey(mainBarTextColor))
            return;

        var xfMainColor = (Xamarin.Forms.Color)xfResources[mainColor];
        var xfMainBarTextColor = (Xamarin.Forms.Color)xfResources[mainBarTextColor];

        var uiMainColor = UIColor.FromRGB(
            (nfloat)xfMainColor.R,
            (nfloat)xfMainColor.G,
            (nfloat)xfMainColor.B
        );

        var uiMainBarTextColor = UIColor.FromRGB(
            (nfloat)xfMainBarTextColor.R,
            (nfloat)xfMainBarTextColor.G,
            (nfloat)xfMainBarTextColor.B
        );

        UIView.Appearance.TintColor = uiMainColor;
    }
}

Agora sim a pessoa programadora vibra e diz:

eu te disse que tinha feito...
Dialog exibido com bot√Ķes em cor customizada
Dialog exibido com bot√Ķes em cor customizada

Por fim, faremos mais uma implementação, que consiste em exibir uma imagem utilizando o visualizador de arquivos padrão de cada plataforma. Neste exemplo, utilizaremos o DependencyService para invocar o QuickLookPreview do iOS para chamar uma imagem que está na pasta Resources da plataforma. Vamos ver como fica:

QuickLookPreview com bot√Ķes em cor customizada
QuickLookPreview com bot√Ķes em cor customizada

U√©, mas‚Ķ Onde est√° a barra de navega√ß√£o com aquela cor esperta que hav√≠amos definido?? Sim, definimos, por√©m, realizamos no objeto NavigationPage do Xamarin.Forms. Como utilizamos DependencyService para chamar uma view direto do iOS, as configura√ß√Ķes de estilo permaneceram as padr√Ķes do iOS, por isso essa barra branca novamente.

Pelo menos o botão Done e o de compartilhamento já estão verdes, mas isso é graças a definição do estilo no UIView, caso contrário eles estariam azuis.

E agora, como resolver? Vamos voltar no AppDelegate.cs no método de estilo que criamos, e vamos adicionar o estilo ao UINavigationBar.

private void BuildStyles()
{
    var xfResources = Xamarin.Forms.Application.Current.Resources;
    if (xfResources == null)
        return;

    var mainColor = "MainColor";
    var mainBarTextColor = "MainBarTextColor";

    if (!xfResources.ContainsKey(mainColor) || !xfResources.ContainsKey(mainBarTextColor))
        return;

    var xfMainColor = (Xamarin.Forms.Color)xfResources[mainColor];
    var xfMainBarTextColor = (Xamarin.Forms.Color)xfResources[mainBarTextColor];

    var uiMainColor = UIColor.FromRGB(
        (nfloat)xfMainColor.R,
        (nfloat)xfMainColor.G,
        (nfloat)xfMainColor.B
    );

    var uiMainBarTextColor = UIColor.FromRGB(
        (nfloat)xfMainBarTextColor.R,
        (nfloat)xfMainBarTextColor.G,
        (nfloat)xfMainBarTextColor.B
    );

    UINavigationBar.Appearance.BarTintColor = uiMainColor;
    UINavigationBar.Appearance.TintColor = uiMainBarTextColor;
    UINavigationBar.Appearance.SetTitleTextAttributes(
        new UITextAttributes() { TextColor = uiMainBarTextColor }
    );
    UIView.Appearance.TintColor = uiMainColor;
}

Primeiro, definimos a cor na barra de navega√ß√£o (linha 28). Depois definimos a cor do texto dos bot√Ķes presentes na navega√ß√£o (linha 29). Por √ļltimo, modificamos a cor do texto presente na barra de navega√ß√£o (linhas 30, 31 e 32).

Olha o que temos agora…

QuickLookPreview com navigation bar em cor customizada
QuickLookPreview com navigation bar em cor customizada

Pronto! Agora voc√™ aprendeu como realizar algumas customiza√ß√Ķes nos estilos dos elementos do Xamarin.iOS.

O projeto que utilizei como exemplo est√° no Github, aqui.

O que achou? Deixe seu comentário com sua opinião, sugestão, crítica ou elogio.

Abraço e até a próxima!