Picker doesn’t work for MacCatalyst

If you are creating a project with MAUI and try your application on different platforms, you will soon discover this issue. The Picker doesn’t work for MacCatalyst. And this is quite annoying.

Scenario

So, on your page you added a Picker like the following

<Picker
    ItemDisplayBinding="{Binding Name}"
    ItemsSource="{Binding ServiceConnections}"
    SelectedItem="{Binding SelectedConnection}"
    TextColor="{StaticResource White}"
    TitleColor="LightGray"
    Title="Select an environment..." />

After searching on the internet, I found that a few developers are complaining about this issue. For example, on GitHub. or Stackoverflow. The Maui Picker is a wrapper around a UITextField that fires a UIAlert to show a picker. So, from what I read, I believe the way this worked was by using UITextView. When you tapped it, it will fire an event on edit. This event creates a UIAlertController with an ActionSheet style. It then hijacks the alert by replacing its underlying view with a UIPickerView.

Then, a possible solution is to remove the Title from the Picker if you added one for the Picker. A few people said that the Title caused this problem during the render. So, you can add some conditional around the title like that

<Picker
    ItemDisplayBinding="{Binding Name}"
    ItemsSource="{Binding ServiceConnections}"
    SelectedItem="{Binding SelectedConnection}"
    TextColor="{StaticResource White}"
    TitleColor="LightGray"
    Title="{OnPlatform iOS='Select an environment...',
                       Android='Select an environment...',
                       WinUI='Select an environment...'}" />

In my case, this wasn’t the case and so I still have the issue.

My workaround

This is not very elegant. It allows me to avoid rethinking the UI for my apps. I use the Picker for all platforms apart from MacCatalyst. So, this is my original code to display a SearchBar and a Picker to filter a ListView.

<Grid
	Margin="10,0,10,0"
	ColumnDefinitions="*,Auto"
	RowDefinitions="Auto,Auto"
	HorizontalOptions="FillAndExpand"
	VerticalOptions="FillAndExpand">
    <SearchBar
		x:Name="searchBar"
		Margin="0,0,5,5"
		BackgroundColor="White"
		Placeholder="Search"
		TextChanged="searchBar_TextChanged"
		VerticalOptions="FillAndExpand" />
    <Picker
		x:Name="pickerFilter"
		Grid.Column="1"
		ItemDisplayBinding="{Binding Name}"
		ItemsSource="{Binding Filters}"
		SelectedIndexChanged="pickerFilter_SelectedIndexChanged" />
</Grid>
SearchBar and Picker for iOS - Picker doesn't work for MacCatalyst
SearchBar and Picker for iOS

This is not working for MacCatalyst. So, I hide the Picker when the application runs on it. In one of my previous post, I implemented a tabpage with RadioButton and I’m going to use part of it. The XAML is now like that

			<Grid
				Margin="10,0,10,0"
				ColumnDefinitions="*,Auto"
				RowDefinitions="Auto,Auto"
				HorizontalOptions="FillAndExpand"
				VerticalOptions="FillAndExpand">
				<SearchBar
					x:Name="searchBar"
					Margin="0,0,5,5"
					BackgroundColor="White"
					Placeholder="Search"
					TextChanged="searchBar_TextChanged"
					VerticalOptions="FillAndExpand" />
				<Picker
					x:Name="pickerFilter"
					Grid.Column="1"
					IsVisible="{OnPlatform MacCatalyst='False', Default='True'}"
					ItemDisplayBinding="{Binding Name}"
					ItemsSource="{Binding Filters}"
					SelectedIndexChanged="pickerFilter_SelectedIndexChanged" />

				<HorizontalStackLayout
					BindableLayout.ItemsSource="{Binding Filters}"
					HorizontalOptions="EndAndExpand"
					RadioButtonGroup.GroupName="gpFilter"
					RadioButtonGroup.SelectedValue="{Binding RadioFilter}"
					IsVisible="{OnPlatform MacCatalyst='True', Default='False'}" Grid.Row="1" Grid.ColumnSpan="2">
					<BindableLayout.ItemTemplate>
						<DataTemplate x:DataType="md:FilterModel">
							<RadioButton
								x:Name="radio"
								Margin="0,0,15,0"
								Content="{Binding Name}"
								GroupName="gpFilter"
								HorizontalOptions="FillAndExpand"
								MinimumWidthRequest="60"
								Value="{Binding Value}"
								CheckedChanged="RadioButton_CheckedChanged" />
						</DataTemplate>
					</BindableLayout.ItemTemplate>
				</HorizontalStackLayout>
			</Grid>

Now, the magic happens in the IsVisible condition. Using OnPlatform, I show another component for MacCatalyst.

Implementation explains

Now, I use the same source called Filters that is an ObservableCollection of FilterModel that is my model that has Name and Value. With the HorizontalStackLayout, I use the BindableLayout to display the RadioButton.

What you see when the application runs in MacCatalyst is in the following screenshot

RadioButton replaces Picker
RadioButton replaces Picker

So, the user can see this implementation based on the platform.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.