Skip to content

[iOS] Fix for Shell custom FlyoutIcon display problem #26016

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Jul 25, 2025

Conversation

Tamilarasan-Paranthaman
Copy link
Contributor

@Tamilarasan-Paranthaman Tamilarasan-Paranthaman commented Nov 21, 2024

Issue: The flyout icon is aligned to the center instead of the left, causing the title to extend beyond the view.

Root Cause of the issue

  • The custom image size is too large, causing it to render in the center and leaving extra space on the left.

Description of Change

  • I resized the custom image to match the hamburger size using the UIGraphics concept and implemented caching to prevent redundant image rendering.

Reference for icon size: https://github.com/dotnet/maui/blob/main/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellPageRendererTracker.cs#L450

Issues Fixed

Fixes #25920

Tested the behaviour in the following platforms

  • Android
  • Windows
  • iOS
  • Mac

Screenshot

iOS

Before Issue Fix After Issue Fix

@dotnet-policy-service dotnet-policy-service bot added the community ✨ Community Contribution label Nov 21, 2024
@jsuarezruiz jsuarezruiz added platform/ios area-controls-shell Shell Navigation, Routes, Tabs, Flyout labels Nov 21, 2024
@jsuarezruiz
Copy link
Contributor

jsuarezruiz commented Nov 21, 2024

/azp run

This comment was marked as outdated.

@Tamilarasan-Paranthaman Tamilarasan-Paranthaman marked this pull request as ready for review November 21, 2024 13:19
@Tamilarasan-Paranthaman Tamilarasan-Paranthaman requested a review from a team as a code owner November 21, 2024 13:20
@@ -336,7 +336,7 @@ void UpdateLeftToolbarItems()

if (image != null)
{
icon = result?.Value;
icon = ResizeImage(result?.Value, new CGSize(23f, 23f));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is iOS the only one that doesn't resize?
Is this size correct under all the screen options? (@2x etc) https://developer.apple.com/design/human-interface-guidelines/toolbars

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is iOS the only one that doesn't resize? Is this size correct under all the screen options? (@2x etc) https://developer.apple.com/design/human-interface-guidelines/toolbars

@jsuarezruiz, I have tested the icon under all device screen options, and it works properly on all devices. The size I am using for the custom icon is based on the default Hamburger icon size. Please refer to the code below for your reference

Reference for icon size:

@@ -0,0 +1,27 @@
#if !WINDOWS
// In Windows, the foreground color is not applied to the custom icon,
// so as of now, the test is not applicable for Windows.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Windows is the only one having a different behavior, right?
Could you open a new issue and include the link in the comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Windows is the only one having a different behavior, right? Could you open a new issue and include the link in the comment.

@jsuarezruiz, the new issue for the Windows platform has been logged and I have added a comment. Could you please check and provide your concerns if any?

// https://github.com/dotnet/maui/issues/26148

Copy link

Azure Pipelines successfully started running 3 pipeline(s).

@sheiksyedm sheiksyedm added the partner/syncfusion Issues / PR's with Syncfusion collaboration label Dec 6, 2024
@PureWeen PureWeen self-assigned this Dec 12, 2024
Copy link

Azure Pipelines successfully started running 3 pipeline(s).

@PureWeen
Copy link
Member

/azp run

Copy link

Azure Pipelines successfully started running 3 pipeline(s).

@jsuarezruiz
Copy link
Contributor

/azp run

Copy link

Azure Pipelines successfully started running 3 pipeline(s).

Copy link
Member

@PureWeen PureWeen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you split the android change out from this PR?

I think the resizing parts of this for the iOS Icon is going to need a little bit deeper of an analysis.

Like, I'm curious if users have an icon that's 30x30, or just slightly bigger than 40x40 if we want to resize.

Playing with the sandbox here's a few sizes

I don't know if we can force an opinion here on the size of that icon for users. If this is an issue in our template we should generate an image at the size it should be

30x30
image

23x23
image

40x40
image

@Tamilarasan-Paranthaman Tamilarasan-Paranthaman changed the title [iOS] [Android] Fix for Shell custom FlyoutIcon display problem [iOS] Fix for Shell custom FlyoutIcon display problem Jan 31, 2025
@Ahamed-Ali
Copy link
Contributor

Can you split the android change out from this PR?

I think the resizing parts of this for the iOS Icon is going to need a little bit deeper of an analysis.

Like, I'm curious if users have an icon that's 30x30, or just slightly bigger than 40x40 if we want to resize.

Playing with the sandbox here's a few sizes

I don't know if we can force an opinion here on the size of that icon for users. If this is an issue in our template we should generate an image at the size it should be

30x30 image

23x23 image

40x40 image

Hi @PureWeen , I have created a separate PR 27502 for Android changes. Please review it and share your concerns.

@jsuarezruiz
Copy link
Contributor

/azp run

Copy link

Azure Pipelines successfully started running 3 pipeline(s).

if (maxResizeFactor > 1 && !shouldScaleUp)
return sourceImage;

return UIImage.FromImage(sourceImage.CGImage, sourceImage.CurrentScale / maxResizeFactor, sourceImage.Orientation);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UIImage.FromImage creates a new instance of UIImage with the specified parameters. Could modify the implementation to just transform the current one?

internal static UIImage ResizeImageSource(this UIImage sourceImage, nfloat maxWidth, nfloat maxHeight, CGSize originalImageSize, bool shouldScaleUp = false)
{
	if (sourceImage?.CGImage is null)
		return null;

	maxWidth = (nfloat)Math.Min(maxWidth, originalImageSize.Width);
	maxHeight = (nfloat)Math.Min(maxHeight, originalImageSize.Height);

	var sourceSize = sourceImage.Size;
	var maxResizeFactor = (nfloat)Math.Min(maxWidth / sourceSize.Width, maxHeight / sourceSize.Height);

	if (maxResizeFactor > 1 && !shouldScaleUp)
		return sourceImage;

	var newSize = new CGSize(sourceSize.Width * maxResizeFactor, sourceSize.Height * maxResizeFactor);

	UIGraphics.BeginImageContextWithOptions(newSize, false, 0.0f);
	sourceImage.Draw(new CGRect(0, 0, newSize.Width, newSize.Height));
	var resizedImage = UIGraphics.GetImageFromCurrentImageContext();
	UIGraphics.EndImageContext();

	return resizedImage;
}

This approach uses the image context to resize the image, should be more efficient than creating a new instance.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jsuarezruiz, previously, I used a similar drawing code without scaling in this PR. As per @mattleibow
suggestion, I utilized the ResizeImageSource method from Button.iOS and have now moved it to the UIImageExtensions class as discussed.

Do I need to modify the existing code as you suggested?

please check the previous discussion and share the details:
#26016 (comment)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah for now we can just keep this as is, but maybe create a issue to in another PR try refactor the code to what @jsuarezruiz says

@jsuarezruiz
Copy link
Contributor

@PureWeen Should these changes be a Platform Specific similar to #28046? In that case, should target to the net10.0 branch?

@jsuarezruiz
Copy link
Contributor

/rebase

@dotnet dotnet deleted a comment from azure-pipelines bot Mar 31, 2025
@dotnet dotnet deleted a comment from jsuarezruiz Mar 31, 2025
@rmarinho
Copy link
Member

/azp run

Copy link

Azure Pipelines successfully started running 3 pipeline(s).

Copy link
Member

@rmarinho rmarinho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Address some review feedback and suggestions

@@ -219,4 +219,4 @@ body:
- type: markdown
attributes:
value: |
By opening the issue you agree to follow this project's [Code of Conduct](https://github.com/dotnet/maui/blob/main/.github/CODE_OF_CONDUCT.md)
By opening the issue you agree to follow this project's [Code of Conduct](https://github.com/dotnet/maui/blob/main/.github/CODE_OF_CONDUCT.md)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its adding spaces instead of tabs

@Tamilarasan-Paranthaman
Copy link
Contributor Author

its adding spaces instead of tabs

@rmarinho, Even though I copied the file content from the base branch to my branch and there were no actual changes to push, it's showing as a difference only in the PR, even though there are no real changes locally.

@rmarinho
Copy link
Member

/azp run

Copy link

Azure Pipelines successfully started running 3 pipeline(s).

@rmarinho
Copy link
Member

I saw some issues that I don t think are related to this PR, but seems .svg doesn t work as icon source, and changing the image to avatar.png produce this.

Simulator Screenshot - iPhone Xs (iOS 18 0) - created by XHarness - 2025-07-24 at 17 19 10

@rmarinho
Copy link
Member

And cover1.jpg

Simulator Screenshot - iPhone Xs (iOS 18 0) - created by XHarness - 2025-07-24 at 17 22 55

Copy link
Member

@rmarinho rmarinho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw some issues, but they also reproduce on main, the size/resize of the icon works well this this PR .

@dotnet dotnet deleted a comment from PureWeen Jul 24, 2025
@dotnet dotnet deleted a comment from jsuarezruiz Jul 24, 2025
@dotnet dotnet deleted a comment from azure-pipelines bot Jul 24, 2025
@rmarinho rmarinho merged commit 93bfe35 into dotnet:net10.0 Jul 25, 2025
131 checks passed
@github-project-automation github-project-automation bot moved this from Changes Requested to Done in MAUI SDK Ongoing Jul 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-controls-shell Shell Navigation, Routes, Tabs, Flyout community ✨ Community Contribution p/0 Work that we can't release without partner/syncfusion Issues / PR's with Syncfusion collaboration platform/ios
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

.NET MAUI set AppShell custom FlyoutIcon display problem
7 participants