maui
maui copied to clipboard
MAUI: Shell FlyoutHeader disables the click/selection of first Flyout item on iOS
Description
I'm creating a MAUI Shell app with Flyout and tabs. As soon as I add a Flyout header to the Flyout, it disables the selection of first Flyout item on iOS while other items are still selectable. On android, it works fine. Removing the Flyoutheader fixes this issue. But I need to show a header view in the Flyout.
Steps to Reproduce
Sample code:
`<Shell xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:YourNamespace" x:Class="YourNamespace.AppShell">
<Shell.Resources>
<!-- Define your styles here -->
<Style x:Key="BaseStyle" TargetType="Element">
<!-- Define your base styles -->
</Style>
<Style x:Key="ShellItemStyle" TargetType="Element" BasedOn="{StaticResource BaseStyle}">
<!-- Define styles for ShellItems -->
</Style>
<Style x:Key="TabStyle" TargetType="Element" BasedOn="{StaticResource BaseStyle}">
<!-- Define styles for Tabs -->
</Style>
</Shell.Resources>
<Shell.FlyoutHeaderTemplate>
<DataTemplate>
<StackLayout BackgroundColor="#53A0FD" Padding="12,24,12,12">
<!-- Your header content goes here -->
<Image Source="your_logo.png" HeightRequest="80" WidthRequest="80" />
<Label Text="Your App Name" TextColor="White" FontSize="20" FontAttributes="Bold" />
</StackLayout>
</DataTemplate>
</Shell.FlyoutHeaderTemplate>
<!-- FlyoutItem 1: Today -->
<FlyoutItem Title="Today" Route="Today">
<Tab Title="Calendar" Route="Calendar">
<ShellContent ContentTemplate="{DataTemplate local:CalendarPage}" />
</Tab>
<Tab Title="Alerts" Route="Alerts">
<ShellContent ContentTemplate="{DataTemplate local:AlertsPage}" />
</Tab>
<Tab Title="Messages" Route="Messages">
<ShellContent ContentTemplate="{DataTemplate local:MessagesPage}" />
</Tab>
<Tab Title="More" Route="More">
<ShellContent ContentTemplate="{DataTemplate local:MorePage}" />
</Tab>
</FlyoutItem>
<!-- FlyoutItem 2: Logout -->
<FlyoutItem Title="Logout" Route="Logout">
<ShellContent ContentTemplate="{DataTemplate local:LogoutPage}" />
</FlyoutItem>
<!-- FlyoutItem 3: Tenants -->
<FlyoutItem Title="Tenants" Route="Tenants">
<ShellContent ContentTemplate="{DataTemplate local:TenantsPage}" />
</FlyoutItem>
`
Link to public reproduction project repository
No response
Version with bug
8.0.3
Is this a regression from previous behavior?
Not sure, did not test other versions
Last version that worked well
Unknown/Other
Affected platforms
iOS
Affected platform versions
No response
Did you find any workaround?
Didn't find any workaround yet.
Relevant log output
No response
I had a similar issue with flyout header on ios where it wasnt sizing properly when not using safearea. Ended up removing it and just adding a header to the top of <Shell.FlyoutContent> which uses a grid.
Hi @jeff-eats-pubsubs , can you share a sample of the code to see how you've added the header and other flyout options to the FlyoutContent? It will be really helpful. Thanks in advance!
Having the same issue. This is the simple code I have: `
<Shell x:Class="IOTToolkit.AppShell" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:connections="clr-namespace:IOTToolkit.Views.Connections" xmlns:local="clr-namespace:IOTToolkit" xmlns:settings="clr-namespace:IOTToolkit.Views.Settings" Shell.FlyoutBehavior="Flyout" Shell.ForegroundColor="{AppThemeBinding Dark={StaticResource White}, Light={StaticResource OffBlack}}" Title="IOTToolkit" x:Name="shell" x:DataType="local:AppShell">
<ShellContent
Title="Home"
ContentTemplate="{DataTemplate local:MainPage}"
Route="MainPage" />
<ShellContent
Title="Local connection"
ContentTemplate="{DataTemplate connections:LocalConnectionPage}"
Route="LocalConnectionPage" />
<ShellContent
Title="Cloud"
ContentTemplate="{DataTemplate connections:CloudConnectionPage}"
Route="CloudConnectionPage" />
<ShellContent
Title="Settings"
ContentTemplate="{DataTemplate settings:SettingsPage}"
Route="SettingsPage" />
<Shell.FlyoutHeader>
<Label Text="My Header" />
</Shell.FlyoutHeader>
`
With this code the first item "Home" can not be pressed. Removing Shell.FlyoutHeader
the first item is pressable again.
This is from what i found an issue since xamarin forms. And trying to fix this in impossible outside of the implementation in maui. A lot of internal classes. Main reason for this is a fix Margin down the way.
Workaround:
<Shell.FlyoutHeader> <Frame Margin="0" BackgroundColor="Transparent" BorderColor="Transparent" > <HorizontalStackLayout Padding="8,12,8,0"> <Image Source="test.png" HeightRequest="24" MaximumWidthRequest="101" Aspect="AspectFit"/> </HorizontalStackLayout> </Frame> <Shell.FlyoutHeader>
Use a Frame with Margin="0" ;-)
Having the same issue. As soon as a header is available, the first flyoutItem
is no longer clickable on iOS.
The above mentioned workaround indeed works, BUT destroys the layout of the header if you have a VerticalStackLayout
in it.
@nsood9 Something like this. You can place whatever you'd like in <Shell.FlyoutContent>
AppShell.xaml
<Shell
x:Class="MyMAUI.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:components="clr-namespace:MyMAUI.Components"
xmlns:ios="clr-namespace:Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;assembly=Microsoft.Maui.Controls"
xmlns:startup="clr-namespace:MyMAUI.Views.Startup"
Padding="0,0,0,0"
ios:Page.UseSafeArea="True"
FlyoutBackdrop="{StaticResource Tint}">
<!-- Some <ShellContent>s all with FlyoutItemIsVisible="False"-->
<Shell.FlyoutContent>
<components:FlyoutContentComponent/>
</Shell.FlyoutContent>
</Shell>
FlyoutContentComponent.xaml
<Border
x:Class="MyMAUI.Components.FlyoutContentComponent"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:components="clr-namespace:MyMAUI.components"
x:Name="FlyoutContentBorder"
Margin="0,0,0,0"
Padding="0"
x:DataType="components:FlyoutContentComponent"
Background="White"
InputTransparent="False"
StrokeThickness="0"
VerticalOptions="Fill">
<Grid x:Name="FlyoutGrid" RowDefinitions="300, *, 60">
<Border
x:Name="FlyoutHeader"
Grid.Row="0"
ZIndex="2">
<!-- Content in here is the header -->
</Border>
<ScrollView
x:Name="FlyoutContent"
Grid.Row="1"
ZIndex="1">
<!-- I have nav menu here -->
</ScrollView>
<Border
x:Name="FlyoutFooter"
Grid.Row="2"
ZIndex="2">
<!-- Content in here is the footer-->
</Border>
</Grid>
</Border>
We have the same problem. As soon as we add a Shell.Header, the first item is not clickable.
It used to work with .NET 7 without problems (if that helps anything) and became a problem with .NET 8.
I ran into the same issue. I took a similar approach as @Larhei, but instead of using a Frame
, I used a Border
.
My original code looked like this:
<Shell.FlyoutHeader>
<VerticalStackLayout BackgroundColor="{AppThemeBinding Light={StaticResource Primary},
Dark={StaticResource Secondary}}"
Padding="24">
<Image
HeightRequest="120"
Source="logo.png"
WidthRequest="120" />
<Label
FontSize="24"
HorizontalOptions="Center"
Text="{x:Static strings:AppResources.AppName}"
TextColor="{AppThemeBinding Light={StaticResource PrimaryLightLightest}}" />
</VerticalStackLayout>
</Shell.FlyoutHeader>
I changed it to this
<Shell.FlyoutHeader>
<Border
BackgroundColor="{AppThemeBinding Light={StaticResource Primary},
Dark={StaticResource Secondary}}"
Margin="0"
Padding="24"
StrokeThickness="0">
<VerticalStackLayout Margin="10">
<Image
HeightRequest="120"
Source="logo.png"
WidthRequest="120" />
<Label
FontSize="24"
HorizontalOptions="Center"
Text="{x:Static strings:AppResources.AppName}"
TextColor="{AppThemeBinding Light={StaticResource PrimaryLightLightest}}" />
</VerticalStackLayout>
</Border>
</Shell.FlyoutHeader>
So the changes I made were:
I wrapped the Headers VerticalStackLayout
into a Border
-Element. I moved the BackgroundColor
from my VerticalStackLayout
to the Border
-Element and did the same for thePadding
Property. I set the StrokeThicknes
-Property to 0
to prevent a one pixel border appearing around my header. In addition to that I had to set a Margin
of 10
to my VerticalStackLayout
.
If you don't want to wrap your header in a border
, you can just give your VerticalStackLayout
or Grid
or whatever you're displaying in your header a margin-top and margin-bottom of 36 (like this: margin="0,36"), which is the height of the ios safearea on most modern iOS devices. Although this works, I think the other option looks better because you don't get any white space in the safearea with the border approach.
I hope this helps anybody who runs into the same problem.