MAUI no .NET 11: novidades do RC 2 e o que muda

O MAUI no .NET 11 chegou ao segundo Release Candidate com mudanças que afetam a criação de projetos, o build no Android e o ciclo de vida no iOS. Neste artigo, você vai entender cada novidade do RC 2, ver exemplos práticos e descobrir o que precisa ajustar antes da versão final.
Como o lançamento oficial do .NET 11 está previsto para novembro de 2026, este é o momento ideal para testar. Afinal, um Release Candidate já traz o conjunto de recursos praticamente fechado.
O que é o RC 2 do MAUI no .NET 11
O RC 2 é a segunda versão candidata a lançamento do .NET 11. Em outras palavras, a Microsoft considera o conjunto de recursos estável e foca agora em qualidade e correções.
No caso do MAUI no .NET 11, a Microsoft declarou que o objetivo principal do ciclo é melhorar a qualidade do produto. Por isso, muitas novidades deste RC são ajustes de build, desempenho e compatibilidade com as plataformas.
Ainda assim, o RC 2 traz recursos novos e relevantes. Entre eles, estão um template com interface escrita em C#, suporte ao Apple Icon Composer e um Shell baseado em handlers para iOS.
Além disso, o workload do Android ganhou bindings da API 37.2, suporte ao JDK 25 e mudanças no R8. Já os workloads da Apple passam a exigir o Xcode 27.0.
Se você acompanha a evolução da plataforma, vale lembrar que o .NET 11 também trouxe novidades em outras frentes. Os Blazor AI components, por exemplo, mostram como a versão avança no desenvolvimento web.
Interface em C# no template do MAUI no .NET 11
A novidade mais visível do MAUI no .NET 11 RC 2 está no template maui. Agora, você pode gerar um projeto com a interface escrita totalmente em C#, sem depender de nenhuma biblioteca extra.
Para isso, basta usar a opção --ui csharp no momento da criação do projeto:
dotnet new maui -n MyApp --ui csharp
Com esse comando, o template gera os arquivos App.cs, AppShell.cs e MainPage.cs. Dessa forma, o Shell e as páginas nascem em C#, o que agrada quem prefere evitar XAML.
No entanto, o template mantém o App.xaml e os dicionários de estilo em XAML. Isso acontece porque esses arquivos guardam os recursos da aplicação, como cores e estilos.
Um exemplo simples de página escrita em C# ajuda a visualizar o resultado:
namespace MyApp;
public class MainPage : ContentPage
{
private int _count;
public MainPage()
{
// Cria o botão e registra o evento de clique
var counterButton = new Button { Text = "Click me" };
counterButton.Clicked += (sender, args) =>
{
_count++;
counterButton.Text = $"Clicked {_count} times";
};
Content = new VerticalStackLayout
{
Padding = 30,
Spacing = 25,
Children =
{
new Label { Text = "Hello, MAUI!", FontSize = 32 },
counterButton
}
};
}
}
Vale destacar que o XAML continua como padrão no template. Além disso, a opção --sample-content segue disponível apenas para projetos em XAML.
Projeto desktop com Avalonia
O template multiprojeto também ganhou uma opção nova. Com ela, você adiciona um projeto desktop baseado em Avalonia à solução:
dotnet new maui-multiproject -n MyApp --avalonia
Na prática, essa opção cria apenas o projeto desktop. Ou seja, ela não adiciona nenhum projeto de WebAssembly à solução.
Ícones do Apple Icon Composer
No MAUI no .NET 11 RC 2, o item MauiIcon aceita pacotes .icon do Apple Icon Composer no iOS e no Mac Catalyst. Nesse caso, o compilador de assets da Apple processa o pacote diretamente.
Antes, o Resizetizer convertia o ícone em imagens raster. Com a mudança, o app aproveita o formato nativo da Apple e os recursos visuais mais recentes do sistema.
Para adotar o recurso, você troca o item atual por itens específicos de cada plataforma. Por outro lado, Android e Windows continuam usando um ícone em SVG ou PNG:
<ItemGroup>
<!-- Ícone do Icon Composer para iOS e Mac Catalyst -->
<MauiIcon Include="Resources\AppIcon\appicon.icon"
Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios' Or $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'" />
<!-- Ícone em SVG para Android e Windows -->
<MauiIcon Include="Resources\AppIcon\appicon.svg"
ForegroundFile="Resources\AppIcon\appiconfg.svg"
Color="#512BD4"
Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) != 'ios' And $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) != 'maccatalyst'" />
</ItemGroup>
Lembre de usar apenas um ícone por plataforma alvo. Além disso, o MAUI acompanha as alterações dentro da pasta .icon para builds incrementais.
O nome do ícone do app vem do nome da pasta .icon. Enquanto isso, o processamento de ícones em SVG e PNG continua igual ao das versões anteriores.
Shell handler no iOS e Mac Catalyst
O MAUI no .NET 11 permite que apps de iOS e Mac Catalyst usem uma implementação do Shell baseada em handlers. Para ativar, basta adicionar uma propriedade ao arquivo do projeto:
<PropertyGroup>
<!-- Ativa o Shell baseado em handlers no iOS e Mac Catalyst -->
<UseiOSShellHandler>true</UseiOSShellHandler>
</PropertyGroup>
Essa implementação usa os gerenciadores compartilhados de navegação, barra de abas e flyout. Além disso, ela expõe pontos de extensão para você personalizar os handlers.
Contudo, o ShellRenderer de compatibilidade continua como padrão. Se você remover a propriedade ou definir o valor como false, o app volta a usar o renderer antigo.
Um detalhe importante é que a propriedade registra toda a hierarquia de handlers do Shell. Portanto, você não precisa registrar nenhum handler manualmente.
Expressões C# no XAML do MAUI no .NET 11
As expressões C# dentro do XAML ganharam recursos novos neste RC. Para usar esse recurso no MAUI no .NET 11, você precisa ativar a geração de código do XAML e os recursos em preview:
<PropertyGroup>
<!-- Usa o source generator para inflar o XAML -->
<MauiXamlInflator>SourceGen</MauiXamlInflator>
<EnablePreviewFeatures>true</EnablePreviewFeatures>
</PropertyGroup>
Com isso, as expressões passam a aceitar referências de tipo por meio de prefixos de namespace XML. Além disso, elas permitem acessar propriedades anexadas, como Grid.Row.
Veja um exemplo que exibe a linha do grid em que um botão está posicionado:
<ContentPage
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MyApp.Helpers"
x:Class="MyApp.MainPage">
<Grid RowDefinitions="Auto,Auto,Auto">
<Button x:Name="myButton" Grid.Row="2" />
<Label Text="{$'Row {myButton.(Grid.Row)}'}" />
</Grid>
</ContentPage>
Nesse caso, o gerador converte myButton.(Grid.Row) na chamada ao getter da propriedade anexada. Da mesma forma, uma expressão como {local:Helper.GetValue()} resolve o tipo pelo prefixo do namespace.
No entanto, existe uma limitação importante. Essas expressões não funcionam com o XamlC nem com a inflação em tempo de execução, apenas com o source generator.
O RC 2 também corrige bindings gerados que atribuem uma subpropriedade de struct. Além disso, ele melhora os diagnósticos de strings interpoladas e de grupos de métodos em lambdas.
Por fim, o SourceGen agora resolve bindings com x:Reference dentro de data templates criados sob demanda. Esse cenário era comum em listas e causava erros difíceis de diagnosticar.
XAML Incremental Hot Reload
O XAML Incremental Hot Reload estreou no Preview 7 e ainda é um recurso em preview no MAUI no .NET 11. Ele aplica as alterações do XAML em todas as instâncias vivas de uma página, sem recriá-las.
No RC 2, alterar o StringFormat de um binding preserva a origem x:Reference durante o Hot Reload. Ou seja, você ajusta a formatação sem quebrar a ligação com o elemento de origem.
Além disso, dicionários de recursos sem classe, mesclados pelo App.xaml, agora propagam as edições. Assim, os consumidores de DynamicResource existentes e novos recebem os valores atualizados.
Outra melhoria adia a ativação dos handlers internos até que alguém solicite um handler. Dessa forma, o app evita trabalho desnecessário durante a inicialização.
Novidades do Android no MAUI no .NET 11
O workload do Android concentra boa parte das mudanças do RC 2. Por isso, quem publica apps Android com o MAUI no .NET 11 deve revisar esta seção com atenção.
API 37.2 e JDK 25
No MAUI no .NET 11, o workload inclui os bindings da API 37.2 do Android. Para usar essas APIs, você define o target framework net11.0-android37.2 no projeto.
Além disso, os projetos Android passam a aceitar o JDK 25, além do JDK 21. Contudo, o JDK 21 continua como versão mínima suportada.
Existe um cuidado extra para quem usa Gradle. Nesse caso, projetos que executam o Gradle com o JDK 25 precisam do Gradle 9.1 ou superior.
R8 com otimização e ofuscação
Quando o R8 está ativo, o .NET 11 define AndroidR8ObfuscationMode como private-members por padrão. Com isso, o R8 passa a otimizar o código e pode renomear membros Java privados.
Por outro lado, os nomes de classes Java e de membros públicos e protegidos continuam preservados. Isso garante a interoperabilidade entre o código gerenciado e o Java.
Se o seu app depende da política anterior, você pode restaurá-la com a configuração de compatibilidade:
<PropertyGroup>
<!-- Mantém o shrinking, mas desativa a ofuscação -->
<AndroidR8ObfuscationMode>disabled</AndroidR8ObfuscationMode>
</PropertyGroup>
Essa configuração mantém a remoção de código não usado, mas desliga a ofuscação. Além disso, ela volta à configuração anterior, sem otimização.
Vale notar que o RC 2 não inclui a abordagem experimental de reescrita de assemblies gerenciados para o R8. Portanto, esse recurso fica para versões futuras.
Builds incrementais e pacotes menores
Builds de Release sem alterações agora pulam a geração do APK universal. Isso vale quando o projeto usa a assinatura padrão e nenhum argumento extra do bundletool.
Nos testes da Microsoft, o comando dotnet build --no-restore repetido caiu de 6,72 para 4,58 segundos. Ou seja, houve uma redução de 31,8% no tempo de build.
Entretanto, projetos com keystore personalizada ou argumentos próprios do bundletool mantêm o comportamento anterior. Nesses casos, a etapa continua rodando em todo build.
Os builds otimizados também usam um nível maior de compressão Zstandard no assembly store. Em um app de exemplo para android-arm64, o APK caiu de 22,5 MB para 21,5 MB, uma redução de 4,67%.
Segundo a Microsoft, a comparação no emulador ARM64 com Android 16 não mostrou mudança significativa no tempo de inicialização. Assim, o pacote fica menor sem prejudicar o startup.
Além disso, o CoreCLR e o NativeAOT passam a usar uma região curta sem coleta de lixo durante a inicialização. Essa região termina na primeira chamada a Activity.ReportFullyDrawn() ou após 10 segundos.
Plataformas Apple: Xcode 27 e novos recursos
Para as plataformas Apple, o MAUI no .NET 11 RC 2 exige o Xcode 27.0. Além disso, ele atualiza os bindings de frameworks como UIKit, AppKit, AVFoundation e WebKit.
O NSUrlSessionHandler agora aceita proxies HTTP personalizados. Para isso, você configura a propriedade Proxy com um IWebProxy:
// Configura um proxy personalizado para o handler nativo
var proxy = new WebProxy("http://proxy.example.com:8080");
var handler = new NSUrlSessionHandler
{
Proxy = proxy
};
var client = new HttpClient(handler);
var response = await client.GetStringAsync("https://api.example.com/orders");
Contudo, o handler escolhe o proxy com base no destino da primeira requisição. Por isso, use handlers separados para destinos que exigem configurações diferentes.
Se preferir ignorar o proxy do sistema, defina UseProxy como false. Além disso, as credenciais do proxy valem apenas para destinos HTTPS, por meio de túneis CONNECT.
Outra novidade permite adicionar, sobrescrever ou remover entradas do Info.plist direto no MSBuild. Para isso, você usa itens tipados AppManifestEntry, com valores booleanos, strings ou listas de strings.
Por fim, os apps com CoreCLR no iOS, tvOS e Mac Catalyst agora informam corretamente o suporte a código dinâmico. Assim, bibliotecas como o Entity Framework Core criam modelos em tempo de execução sem cair no caminho do NativeAOT.
Breaking changes do MAUI no .NET 11
O RC 2 lista algumas mudanças incompatíveis com o .NET 10. Por isso, antes de migrar para o MAUI no .NET 11, revise cada uma delas no seu projeto.
A primeira afeta o ciclo de vida no iOS e no Mac Catalyst. Apps compilados com os SDKs do Xcode 27 precisam usar o ciclo de vida baseado em scenes do UIKit.
Os novos templates já incluem um UIApplicationSceneManifest e uma subclasse registrada de MauiUISceneDelegate. No entanto, apps existentes precisam adicionar essa configuração manualmente.
Além disso, você precisa migrar o tratamento personalizado de ciclo de vida e de opções de inicialização para os callbacks de scene. Os templates, por sua vez, mantêm uma única janela como padrão.
Há também um detalhe sobre atalhos. Cada registro de PerformActionForShortcutItem precisa confirmar o callback de conclusão, e quem não trata a ação deve responder com false.
A segunda mudança envolve o Mac Catalyst. Os novos templates definem SupportedOSPlatformVersion como 17.0, que é o mínimo aceito pelo SDK do Mac Catalyst 27.
Enquanto isso, o mínimo para iOS continua em 15.0. Portanto, apenas projetos que miram o Mac Catalyst precisam revisar essa configuração.
A terceira mudança atinge os handlers legados de CollectionView e CarouselView no iOS e no Mac Catalyst. Agora, essas APIs geram avisos de obsolescência.
Nesse caso, você deve migrar handlers personalizados para as implementações Items2. Vale destacar que os controles em si não ficaram obsoletos, e as APIs equivalentes no Windows continuam suportadas.
A última mudança é o novo padrão do R8, que você já viu na seção sobre Android. Por isso, teste qualquer código que busca membros Java pelo nome.
O que mudou desde o RC 1
Além dos recursos novos, o RC 2 do MAUI no .NET 11 alterou alguns padrões definidos no RC 1. Esses ajustes podem mudar o tamanho do app ou o comportamento do build.
Primeiro, os apps com CoreCLR no iOS, tvOS e Mac Catalyst passam a herdar DynamicCodeSupport=true do SDK. Com isso, o System.Reflection.Emit permanece no resultado do trimming.
Essa mudança pode aumentar o tamanho do app. Por isso, se as suas dependências não precisam de código dinâmico, defina a propriedade explicitamente:
<PropertyGroup>
<!-- Reduz o tamanho do app quando nenhuma dependência usa código dinâmico -->
<DynamicCodeSupport>false</DynamicCodeSupport>
</PropertyGroup>
Em seguida, o ReadyToRun no Android passou a exigir trimming. Builds com CoreCLR e PublishTrimmed=false agora desativam o ReadyToRun e emitem o aviso XA0119.
Os bindings gerados para Android também usam a API 24 como mínimo para atributos de plataforma. Assim, APIs depreciadas até esse nível podem gerar avisos comuns de obsolescência.
Por fim, builds de Release para macOS e Mac Catalyst com deployment target 27.0 ou superior mudaram de comportamento. Sem um runtime identifier definido, eles agora usam a arquitetura do host em vez de gerar um app universal.
Para garantir um build universal, defina o deployment target ou os RuntimeIdentifiers cedo. A recomendação da Microsoft é usar o Directory.Build.props ou a linha de comando.
Como migrar para o MAUI no .NET 11
Como a versão final sai em novembro, vale preparar a migração desde já. Primeiro, crie uma branch separada e atualize o target framework dos projetos para o .NET 11.
Em seguida, instale o Xcode 27.0 se o seu app roda em iOS ou Mac Catalyst. Depois disso, implemente o ciclo de vida baseado em scenes, que é a mudança mais trabalhosa desta versão.
No Android, rode os testes com o R8 ativo e o novo modo de ofuscação. Se algo quebrar por causa de reflexão, use temporariamente o valor disabled enquanto corrige o código.
Além disso, revise handlers personalizados de CollectionView e CarouselView nas plataformas Apple. Assim, você evita surpresas quando os avisos virarem erros em versões futuras.
Para conhecer todos os detalhes, consulte a página oficial What's new in .NET MAUI for .NET 11 no Microsoft Learn. Ela reúne as novidades de todos os previews e RCs.
Por fim, se você está começando no ecossistema, os cursos do balta.io ajudam a construir a base em C# e .NET. Com essa base, a migração entre versões fica muito mais tranquila.
Conclusão sobre o MAUI no .NET 11
O RC 2 do MAUI no .NET 11 combina recursos novos com ajustes de qualidade e desempenho. Entre os destaques, estão o template com UI em C#, o Shell handler no iOS e as expressões C# no XAML.
No Android, o build ficou mais rápido e os pacotes ficaram menores. Por outro lado, o novo padrão do R8 exige testes cuidadosos em apps que usam reflexão.
Já nas plataformas Apple, o Xcode 27 e o ciclo de vida baseado em scenes representam a maior mudança. Portanto, comece por eles ao planejar a migração.
Em resumo, o MAUI no .NET 11 caminha para uma versão final mais estável e previsível. Então, aproveite o RC 2 para testar o seu app e chegar preparado ao lançamento de novembro.
FAQ
Quando sai a versão final do .NET 11?
A Microsoft prevê o lançamento oficial do .NET 11 para novembro de 2026. O RC 2 já traz o conjunto de recursos praticamente definitivo.
O XAML deixou de ser o padrão no MAUI?
Não. O XAML continua como padrão no template, e a interface em C# é apenas uma opção ativada com --ui csharp.
Preciso do Xcode 27 para usar o RC 2?
Sim, se o seu app roda em iOS, Mac Catalyst, macOS ou tvOS. Os workloads da Apple no RC 2 exigem o Xcode 27.0.
Como volto ao comportamento antigo do R8?
Defina AndroidR8ObfuscationMode como disabled no arquivo do projeto. Assim, o R8 mantém o shrinking, mas desativa a ofuscação e a otimização.
O Shell handler no iOS já é o padrão?
Ainda não. O ShellRenderer continua como padrão, e você ativa o novo handler com a propriedade UseiOSShellHandler.