[iOS] Fix Span TapGestureRecognizer hitbox misalignment in FormattedString when font contains a STAT table - #36564
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 36564Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 36564" |
|
Azure Pipelines: Successfully started running 1 pipeline(s). There may be pipelines that require an authorized user to comment /azp run to run. |
This comment has been minimized.
This comment has been minimized.
MauiBot
left a comment
There was a problem hiding this comment.
Expert Review — 1 findings
See inline comments for details.
…pe stageDependencies) Regression from 4917a9e. The UpdateComment job gated its deep-artifact download on a JOB-level variable: runDeepUITestsResult: $[ dependencies.RunDeepUITests.result ] At JOB scope, `dependencies.<Name>` resolves SAME-STAGE jobs, not sibling stages, so `dependencies.RunDeepUITests.result` silently resolved to EMPTY. The download condition in(<empty>, 'Succeeded','SucceededWithIssues','Failed') was therefore always false -> the deep artifact was NEVER downloaded -> the aggregator saw no categories -> the summary posted the false warning 'No UI test results were produced for the detected categories' even when deep ran fine and published its artifact. Observed on build 14651727 / PR #36564: the Label deep category was detected, ran 18 min, captured diagnostics, and published drop-ios_ui_tests-controls-Label -- yet the summary claimed no results. (The sibling vars aiSummaryReviewId and trustedGateResult in the same block already correctly use stageDependencies.) Fixes: 1. Root cause: use stageDependencies.RunDeepUITests.result (correct cross-stage context at job scope). 2. Defense-in-depth: gate the download on ne(result,'Skipped') instead of an in()-allowlist, so we skip ONLY when deep is DEFINITIVELY Skipped and err toward SHOWING results for any other/unknown value. Hiding real results is far worse than a cosmetic yellow; continueOnError absorbs a missing artifact. The stage-level references (UpdateAISummaryComment stage condition and the AnalyzeCopilotTokenUsage stage variable) correctly keep `dependencies` -- that is the right context at STAGE scope. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 15d2af20-e4ab-4e88-9011-cfbd83513bc0
This comment has been minimized.
This comment has been minimized.
MauiBot
left a comment
There was a problem hiding this comment.
Expert Review — 2 findings
See inline comments for details.
MauiBot
left a comment
There was a problem hiding this comment.
AI Review Summary
@devanathan-vaithiyanathan — new AI review results are available based on this last commit:
e247aef. To request a fresh review after new comments or commits, comment/review rerun.
🗂️ Review Sessions — click to expand
🚦 Gate — Test Before & After Fix
Gate Result: ✅ PASSED
Platform: IOS · Base: main · Merge base: 0395a53b
| Test | Without Fix (expect FAIL) | With Fix (expect PASS) |
|---|---|---|
🖥️ Issue36505 Issue36505 |
✅ FAIL — 270s | ✅ PASS — 104s |
🔴 Without fix — 🖥️ Issue36505: FAIL ✅ · 270s
Determining projects to restore...
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/BindingSourceGen/Controls.BindingSourceGen.csproj (in 433 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Graphics/src/Graphics/Graphics.csproj (in 441 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Essentials/src/Essentials.csproj (in 4.95 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/Foldable/src/Controls.Foldable.csproj (in 5.13 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Xaml/Controls.Xaml.csproj (in 5.14 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Core/Controls.Core.csproj (in 5.14 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/BlazorWebView/src/Maui/Microsoft.AspNetCore.Components.WebView.Maui.csproj (in 5.14 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj (in 5.14 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/Maps/src/Controls.Maps.csproj (in 5.14 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj (in 5.16 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/Core/maps/src/Maps.csproj (in 5.17 sec).
/Users/cloudtest/vss/_work/1/s/.dotnet/packs/Microsoft.iOS.Sdk.net10.0_26.0/26.0.11017/targets/Xamarin.Shared.Sdk.targets(309,3): warning : RuntimeIdentifier was set on the command line, and will override the value for RuntimeIdentifiers set in the project file. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-ios]
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/net10.0-ios26.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Debug/net10.0-ios26.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Core/Debug/net10.0-ios26.0/Microsoft.Maui.dll
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Maps/Debug/net10.0-ios26.0/Microsoft.Maui.Maps.dll
Controls.BindingSourceGen -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
Controls.Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Maps/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.Maps.dll
Controls.Xaml -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.Xaml.dll
Controls.Foldable -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Foldable/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.Foldable.dll
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
Microsoft.AspNetCore.Components.WebView.Maui -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Microsoft.AspNetCore.Components.WebView.Maui/Debug/net10.0-ios26.0/Microsoft.AspNetCore.Components.WebView.Maui.dll
Detected signing identity:
Code Signing Key: "" (-)
Provisioning Profile: "" () - no entitlements
Bundle Id: com.microsoft.maui.uitests
App Id: com.microsoft.maui.uitests
Controls.TestCases.HostApp -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-ios/iossimulator-arm64/Controls.TestCases.HostApp.dll
Optimizing assemblies for size may change the behavior of the app. Be sure to test after publishing. See: https://aka.ms/dotnet-illink
Optimizing assemblies for size. This process might take a while.
Build succeeded.
/Users/cloudtest/vss/_work/1/s/.dotnet/packs/Microsoft.iOS.Sdk.net10.0_26.0/26.0.11017/targets/Xamarin.Shared.Sdk.targets(309,3): warning : RuntimeIdentifier was set on the command line, and will override the value for RuntimeIdentifiers set in the project file. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-ios]
1 Warning(s)
0 Error(s)
Time Elapsed 00:02:17.18
Determining projects to restore...
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/tests/CustomAttributes/Controls.CustomAttributes.csproj (in 678 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/VisualTestUtils/VisualTestUtils.csproj (in 678 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/BindingSourceGen/Controls.BindingSourceGen.csproj (in 659 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/UITest.Core/UITest.Core.csproj (in 670 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Essentials/src/Essentials.csproj (in 762 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Graphics/src/Graphics/Graphics.csproj (in 76 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Core/Controls.Core.csproj (in 780 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj (in 801 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/UITest.NUnit/UITest.NUnit.csproj (in 1.63 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/UITest.Appium/UITest.Appium.csproj (in 2.09 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/UITest.Analyzers/UITest.Analyzers.csproj (in 3.02 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/VisualTestUtils.MagickNet/VisualTestUtils.MagickNet.csproj (in 3.08 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/tests/TestCases.iOS.Tests/Controls.TestCases.iOS.Tests.csproj (in 3.81 sec).
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
Controls.CustomAttributes -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.CustomAttributes/Debug/net10.0/Controls.CustomAttributes.dll
Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
Controls.BindingSourceGen -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
UITest.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.Core/Debug/net10.0/UITest.Core.dll
VisualTestUtils -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/VisualTestUtils/Debug/netstandard2.0/VisualTestUtils.dll
UITest.NUnit -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.NUnit/Debug/net10.0/UITest.NUnit.dll
VisualTestUtils.MagickNet -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/VisualTestUtils.MagickNet/Debug/netstandard2.0/VisualTestUtils.MagickNet.dll
UITest.Appium -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.Appium/Debug/net10.0/UITest.Appium.dll
UITest.Analyzers -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.Analyzers/Debug/netstandard2.0/UITest.Analyzers.dll
Controls.TestCases.iOS.Tests -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.iOS.Tests/Debug/net10.0/Controls.TestCases.iOS.Tests.dll
Test run for /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.iOS.Tests/Debug/net10.0/Controls.TestCases.iOS.Tests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (arm64)
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.05] Discovering: Controls.TestCases.iOS.Tests
[xUnit.net 00:00:00.14] Discovered: Controls.TestCases.iOS.Tests
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.iOS.Tests/Debug/net10.0/Controls.TestCases.iOS.Tests.dll
NUnit3TestExecutor discovered 1 of 1 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 7/14/2026 10:46:01 AM FixtureSetup for Issue36505(iOS)
>>>>> 7/14/2026 10:46:06 AM SpanTapHitboxShouldAlignWithRenderedTextWhenFontHasStatTable Start
>>>>> 7/14/2026 10:46:10 AM SpanTapHitboxShouldAlignWithRenderedTextWhenFontHasStatTable Stop
>>>>> 7/14/2026 10:46:10 AM Log types: syslog, crashlog, performance, safariConsole, safariNetwork, server
Failed SpanTapHitboxShouldAlignWithRenderedTextWhenFontHasStatTable [4 s]
Error Message:
Tapping the span at its visual position should trigger the TapGestureRecognizer
Assert.That(App.WaitForTextToBePresentInElement("StatusLabel", "Success", timeout: TimeSpan.FromSeconds(3)), Is.True)
Expected: True
But was: False
Stack Trace:
at Microsoft.Maui.TestCases.Tests.Issues.Issue36505.SpanTapHitboxShouldAlignWithRenderedTextWhenFontHasStatTable() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue36505.cs:line 33
1) at Microsoft.Maui.TestCases.Tests.Issues.Issue36505.SpanTapHitboxShouldAlignWithRenderedTextWhenFontHasStatTable() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue36505.cs:line 33
NUnit Adapter 4.5.0.0: Test execution complete
Results File: /Users/cloudtest/vss/_work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue36505.trx
Total tests: 1
Failed: 1
Test Run Failed.
Total time: 1.3219 Minutes
>>> TRX_RESULT_FILE: /Users/cloudtest/vss/_work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue36505.trx
🟢 With fix — 🖥️ Issue36505: PASS ✅ · 104s
Determining projects to restore...
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/BindingSourceGen/Controls.BindingSourceGen.csproj (in 344 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Graphics/src/Graphics/Graphics.csproj (in 350 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Essentials/src/Essentials.csproj (in 352 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Core/Controls.Core.csproj (in 387 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj (in 399 ms).
6 of 11 projects are up-to-date for restore.
/Users/cloudtest/vss/_work/1/s/.dotnet/packs/Microsoft.iOS.Sdk.net10.0_26.0/26.0.11017/targets/Xamarin.Shared.Sdk.targets(309,3): warning : RuntimeIdentifier was set on the command line, and will override the value for RuntimeIdentifiers set in the project file. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-ios]
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/net10.0-ios26.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Debug/net10.0-ios26.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Core/Debug/net10.0-ios26.0/Microsoft.Maui.dll
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Maps/Debug/net10.0-ios26.0/Microsoft.Maui.Maps.dll
Controls.BindingSourceGen -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
Controls.Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Maps/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.Maps.dll
Controls.Xaml -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.Xaml.dll
Controls.Foldable -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Foldable/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.Foldable.dll
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
Microsoft.AspNetCore.Components.WebView.Maui -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Microsoft.AspNetCore.Components.WebView.Maui/Debug/net10.0-ios26.0/Microsoft.AspNetCore.Components.WebView.Maui.dll
Detected signing identity:
Code Signing Key: "" (-)
Provisioning Profile: "" () - no entitlements
Bundle Id: com.microsoft.maui.uitests
App Id: com.microsoft.maui.uitests
Controls.TestCases.HostApp -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-ios/iossimulator-arm64/Controls.TestCases.HostApp.dll
Optimizing assemblies for size may change the behavior of the app. Be sure to test after publishing. See: https://aka.ms/dotnet-illink
Optimizing assemblies for size. This process might take a while.
Build succeeded.
/Users/cloudtest/vss/_work/1/s/.dotnet/packs/Microsoft.iOS.Sdk.net10.0_26.0/26.0.11017/targets/Xamarin.Shared.Sdk.targets(309,3): warning : RuntimeIdentifier was set on the command line, and will override the value for RuntimeIdentifiers set in the project file. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-ios]
1 Warning(s)
0 Error(s)
Time Elapsed 00:00:49.53
Determining projects to restore...
Restored /Users/cloudtest/vss/_work/1/s/src/Graphics/src/Graphics/Graphics.csproj (in 370 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/BindingSourceGen/Controls.BindingSourceGen.csproj (in 370 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Essentials/src/Essentials.csproj (in 376 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Core/Controls.Core.csproj (in 353 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj (in 410 ms).
8 of 13 projects are up-to-date for restore.
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
Controls.CustomAttributes -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.CustomAttributes/Debug/net10.0/Controls.CustomAttributes.dll
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
Controls.BindingSourceGen -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.100-ci+azdo.14653021
Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
UITest.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.Core/Debug/net10.0/UITest.Core.dll
VisualTestUtils -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/VisualTestUtils/Debug/netstandard2.0/VisualTestUtils.dll
UITest.Appium -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.Appium/Debug/net10.0/UITest.Appium.dll
UITest.NUnit -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.NUnit/Debug/net10.0/UITest.NUnit.dll
VisualTestUtils.MagickNet -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/VisualTestUtils.MagickNet/Debug/netstandard2.0/VisualTestUtils.MagickNet.dll
UITest.Analyzers -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.Analyzers/Debug/netstandard2.0/UITest.Analyzers.dll
Controls.TestCases.iOS.Tests -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.iOS.Tests/Debug/net10.0/Controls.TestCases.iOS.Tests.dll
Test run for /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.iOS.Tests/Debug/net10.0/Controls.TestCases.iOS.Tests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (arm64)
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.04] Discovering: Controls.TestCases.iOS.Tests
[xUnit.net 00:00:00.14] Discovered: Controls.TestCases.iOS.Tests
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.iOS.Tests/Debug/net10.0/Controls.TestCases.iOS.Tests.dll
NUnit3TestExecutor discovered 1 of 1 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 7/14/2026 10:47:49 AM FixtureSetup for Issue36505(iOS)
>>>>> 7/14/2026 10:47:54 AM SpanTapHitboxShouldAlignWithRenderedTextWhenFontHasStatTable Start
>>>>> 7/14/2026 10:47:55 AM SpanTapHitboxShouldAlignWithRenderedTextWhenFontHasStatTable Stop
Passed SpanTapHitboxShouldAlignWithRenderedTextWhenFontHasStatTable [537 ms]
NUnit Adapter 4.5.0.0: Test execution complete
Results File: /Users/cloudtest/vss/_work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue36505.trx
Test Run Successful.
Total tests: 1
Passed: 1
Total time: 22.3133 Seconds
>>> TRX_RESULT_FILE: /Users/cloudtest/vss/_work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue36505.trx
📁 Fix files reverted (1 files)
src/Controls/src/Core/Platform/iOS/Extensions/FormattedStringExtensions.cs
📱 UI Tests — Label
Detected UI test categories: Label
✅ Deep UI tests — 90 passed, 0 failed across 1 category on platform-pool agent (replaces in-process counts above).
🧪 UI Test Execution Results (deep, platform pool)
| Category | Tests | Snapshot diffs |
|---|---|---|
Label |
90/92 ✓ | — |
📎 Download drop-deep-uitests artifact (TRX + snapshot diffs) |
📋 Pre-Flight — Context & Validation
Issue: #36505 - [iOS] Span TapGestureRecognizer hitbox is mispositioned inside FormattedString when the font contains a STAT table (line-height/leading mismatch)
PR: #36564 - [WIP][iOS] Fix Span TapGestureRecognizer hitbox misalignment in FormattedString when font contains a STAT table
Platforms Affected: iOS; MacCatalyst is also affected by the changed .ios.cs implementation and PR test scope
Files Changed: 1 implementation, 4 test/support
Key Findings
- Root issue:
Label.FormattedTextspan hit regions are calculated with TextKit metrics that can diverge from visible UILabel/CoreText rendering when the custom font has an OpenType STAT table. - PR production fix disables
NSLayoutManager.UsesFontLeadingon iOS 16+ and uses MAUIfinalSizefor the text container size instead of stale/zeroUILabel.Bounds. - Prior inline review found the PR's platform gate misses MacCatalyst because
.ios.csalso compiles for MacCatalyst andOperatingSystem.IsIOSVersionAtLeast(16)is false there. - UI test type: Appium UI test, category
Label, target platform for this loop: iOS.
Code Review Summary
Verdict: NEEDS_CHANGES
Confidence: low
Errors: 1 | Warnings: 1 | Suggestions: 0
Key code review findings:
- Error:
FormattedStringExtensions.cs:233MacCatalyst keepsUsesFontLeading=true, so the fix does not apply to a platform the PR marks/tests. - Warning:
Issue36505.cs:41MacCatalyst test offset may compensate for the unfixed hitbox rather than tapping the rendered text position.
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #36564 | TextKit span-position calculation with UsesFontLeading=false on iOS 16+ and finalSize-based text container sizing |
PASSED (Gate, provided) | FormattedStringExtensions.cs, UI test/support files |
Original PR; iOS gate passed, but MacCatalyst platform gate is incomplete |
🔬 Code Review — Deep Analysis
Code Review — PR #36564
Independent Assessment
What this changes: Updates iOS/MacCatalyst formatted Label span hitbox calculation by disabling NSLayoutManager.UsesFontLeading on iOS 16+ and preferring MAUI finalSize over potentially stale UILabel.Bounds. Adds a UI test with a STAT-table custom font.
Inferred motivation: Align Span gesture hit regions with visually rendered text when custom font metrics differ between TextKit hitbox calculation and CoreText/UILabel rendering.
Reconciliation with PR Narrative
Author claims: Fixes #36505 by disabling font leading on iOS 16+ and using finalSize; tested iOS and Mac.
Agreement/disagreement: Matches the iOS intent, but the implementation does not apply the font-leading fix on MacCatalyst despite PR/test scope including MacCatalyst.
Prior Review Reconciliation
| Prior Error Finding | Source | Status | Evidence |
|---|---|---|---|
MacCatalyst keeps UsesFontLeading=true because .ios.cs also compiles for MacCatalyst and OperatingSystem.IsIOSVersionAtLeast(16) is false there. |
MauiBot inline review, FormattedStringExtensions.cs:233 |
Unresolved | Current code still uses UsesFontLeading = !OperatingSystem.IsIOSVersionAtLeast(16). |
Blast Radius Assessment
- Runs for all instances: No; only formatted-text
Labelspan-position recalculation on iOS/MacCatalyst. - Startup impact: No.
- Static/shared state: No.
CI Status
- Required-check result: unavailable;
gh pr checks 36564 --repo dotnet/maui --requiredcould not run becauseghis unauthenticated in this environment. - Classification: undetermined.
- Action taken: Confidence capped low. Public PR metadata and patch were fetched through unauthenticated GitHub API/curl.
Findings
Error — MacCatalyst does not receive the font-leading fix
src/Controls/src/Core/Platform/iOS/Extensions/FormattedStringExtensions.cs:233
This code path also applies to MacCatalyst, but OperatingSystem.IsIOSVersionAtLeast(16) is false on MacCatalyst. MacCatalyst therefore keeps UsesFontLeading=true, so the STAT-table hitbox mismatch remains unfixed for a platform the PR explicitly marks/tests. Use OperatingSystem.IsMacCatalystVersionAtLeast(...) as well, or disable font leading for this TextKit hitbox calculation on both platforms.
Warning — MacCatalyst test offset can mask the unfixed behavior
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue36505.cs:41
The MacCatalyst-specific - visualLineHeight * 0.5f offset appears to compensate for the still-misaligned hitbox rather than tapping the rendered text position. Once the MacCatalyst production fix is applied, this offset should be revisited or the test may validate a workaround instead of the intended behavior.
Failure-Mode Probing
- MacCatalyst with STAT-table font: current PR fix does not apply; hitboxes can remain vertically offset.
- iOS 16+:
UsesFontLeading=falseshould align TextKit hitboxes with rendered text. - iOS <16: behavior remains unchanged.
- Stale/zero
UILabel.Bounds:finalSizeis already validated positive and now drives the text container size. - Handler reconnect/arrange repeats: no new subscriptions or static state.
Verdict: NEEDS_CHANGES
Confidence: low
Summary: The iOS approach is plausible, but MacCatalyst remains unfixed while the PR claims/tests Mac coverage. CI required-check status could not be verified with authenticated gh, further limiting confidence.
🛠️ Fix — Analysis & Comparison
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | try-fix | UILabel/TextKit draw-rect alignment offset | FAIL | 1 file | Did not compile: NSLayoutManager.GetUsedRectForTextContainer is not available in the target binding. |
| 2 | try-fix | CoreText CTFrame/CTLine span rectangle calculation |
FAIL | 1 file | Built and ran iOS UI test, but tap still did not trigger StatusLabel=Success. |
| 3 | try-fix | Preserve TextKit fix but gate UsesFontLeading=false for iOS 16+ OR MacCatalyst 16+ |
PASS (iOS) | 1 file | iOS Issue36505 passed; MacCatalyst build succeeded but Appium launch was environment-blocked. |
| PR | PR #36564 | UsesFontLeading=false on iOS 16+ only plus finalSize text-container sizing |
PASSED (Gate) | 5 files | Original PR passes iOS gate but misses MacCatalyst in .ios.cs code path. |
Cross-Pollination
| Model/Reviewer | Round | New Ideas? | Details |
|---|---|---|---|
| maui-expert-reviewer | 1 | Yes | Suggested TextKit/UILabel offset approach; rejected after compile failure. |
| maui-expert-reviewer | 2 | Yes | Suggested CoreText rewrite; rejected after iOS UI test failure. |
| maui-expert-reviewer | 3 | Yes | Suggested correcting the runtime platform gate while keeping TextKit; passed requested iOS test and fixes reviewed MacCatalyst gap. |
Exhausted: No - stopped because candidate #3 passed the requested iOS test and is demonstrably better than the PR's current fix for the identified MacCatalyst miss.
Selected Fix: Candidate #3 - it is the smallest passing candidate, preserves the PR's validated iOS behavior, and corrects the .ios.cs MacCatalyst gate by using OperatingSystem.IsMacCatalystVersionAtLeast(16) as well as the iOS check.
📝 Recommended PR Title & Description
Assessment: ✏️ Recommend updating — the winning fix extends the UsesFontLeading change to MacCatalyst and removes the MacCatalyst test workaround, so the current [WIP][iOS] title and iOS-only font-leading description are stale.
Recommended title
[iOS/MacCatalyst] Label: Fix FormattedString span tap hitboxes for STAT-table fonts
Recommended description
### Issue Details
When a Label uses FormattedText with a custom font that has an OpenType STAT table, tapping a Span with a TapGestureRecognizer doesn't work correctly on iOS/MacCatalyst. The tap hitbox is vertically offset from where the text is actually drawn — tapping the visible text does nothing, tapping below it fires the event.
### Description of Change
NSLayoutManager.UsesFontLeading is now set to false for span hitbox calculation on iOS 16+ and MacCatalyst 16+ so TextKit uses line metrics that align with the CoreText/UILabel-rendered text, eliminating the vertical offset.
The text container size is also updated to use finalSize (MAUI's layout size) instead of control.Bounds, which can be zero/stale during layout on Mac Catalyst.
The regression test adds a FormattedString Label that uses the STAT-table custom font and taps the rendered "Click me" Span at its visual center. The same visual-center tap formula is used for iOS and MacCatalyst so the test verifies the hitbox alignment instead of compensating for an offset.
### Issues Fixed
Fixes #36505
**Tested the behavior in the following platforms.**
- [ ] Android
- [ ] Windows
- [x] iOS
- [ ] Mac
| Before | After |
|---------|--------|
| **iOS**<br> <video src="https://github.com/user-attachments/assets/622bbc78-ea45-48a3-8433-53a6ed2b1ce9" width="300" height="600"> | **iOS**<br> <video src="https://github.com/user-attachments/assets/e42b373b-6d5f-4982-8106-fd4f66ea0aff" width="300" height="600"> |
🏁 Report — Final Recommendation
Comparative Report — PR #36564
Ranking
| Rank | Candidate | Regression result | Assessment |
|---|---|---|---|
| 1 | pr-plus-reviewer |
PASS-equivalent for requested iOS path; no iOS behavior change beyond raw PR, and applies reviewer fixes | Best candidate. Preserves the passing PR/try-fix-3 TextKit approach, extends the production fix to MacCatalyst, and removes the MacCatalyst test workaround that could mask the bug. |
| 2 | try-fix-3 |
PASS on iOS; MacCatalyst build passed, runtime launch environment-blocked | Strong production fix. It corrects the MacCatalyst UsesFontLeading gate while preserving iOS behavior, but it does not address the test's MacCatalyst half-line compensation. |
| 3 | pr |
PASS on iOS gate | Good iOS fix, but incomplete for MacCatalyst because .ios.cs also compiles there and OperatingSystem.IsIOSVersionAtLeast(16) remains false on MacCatalyst. |
| 4 | try-fix-2 |
FAIL | CoreText rewrite built and ran, but the iOS UI test still failed to trigger the span tap. It is also higher risk for truncation, multi-line ranges, RTL, and composed-character cases. |
| 5 | try-fix-1 |
FAIL | UILabel/TextKit offset approach did not compile because the target binding lacks NSLayoutManager.GetUsedRectForTextContainer. |
Candidate analysis
pr
The raw PR fix addresses the demonstrated iOS failure by disabling TextKit font leading on iOS 16+ and using MAUI finalSize for the text container. The provided gate confirms the new iOS test catches the issue and passes with the PR fix. However, the same implementation file participates in MacCatalyst builds; the iOS-only runtime check leaves MacCatalyst on the old TextKit metric behavior while the PR describes and marks Mac coverage.
pr-plus-reviewer
This candidate applies the expert reviewer's actionable feedback to the raw PR. It keeps the focused TextKit approach and finalSize sizing, adds OperatingSystem.IsMacCatalystVersionAtLeast(16) to the font-leading gate, and removes the MacCatalyst-specific test tap offset. This is the smallest candidate that addresses both the verified iOS regression and the reviewed MacCatalyst correctness gap.
try-fix-1
This candidate attempted to keep default TextKit font leading and adjust span rectangles by the difference between UILabel's drawn text rect and TextKit's used rect. It failed compilation because NSLayoutManager.GetUsedRectForTextContainer is not available in the target bindings, so it cannot be selected.
try-fix-2
This candidate replaced the TextKit hitbox calculation with a CoreText CTFrame/CTLine implementation. It compiled after iteration but failed the iOS regression test, so it must rank below every passing candidate. Its broader rewrite also has more regression surface than the PR's localized TextKit metric adjustment.
try-fix-3
This candidate keeps the PR's TextKit approach and corrects the runtime platform gate for both iOS 16+ and MacCatalyst 16+. It passed the requested iOS test and compiled for MacCatalyst, but the MacCatalyst Appium run was environment-blocked. It is better than the raw PR, but pr-plus-reviewer is stronger because it also removes the test compensation that could hide the MacCatalyst bug.
Winner
Winner: pr-plus-reviewer.
It is the single best candidate because it preserves the only passing production approach, fixes the MacCatalyst gap found by expert review, and aligns the UI test with the intended behavior. The failed try-fix candidates rank lower per the required rule, and the raw PR ranks below candidates that address the unresolved MacCatalyst issue.
🧭 Next Steps — review latest findings
No alternative fix was selected for this run. Review the session findings and CI results before merging.
|
Azure Pipelines: Successfully started running 1 pipeline(s). There may be pipelines that require an authorized user to comment /azp run to run. |
There was a problem hiding this comment.
Pull request overview
Fixes iOS (and Mac Catalyst) Span TapGestureRecognizer hit-testing for Label.FormattedText when custom fonts contain an OpenType STAT table, by making the hitbox layout use the same line metrics as the text rendering path.
Changes:
- Adjusts iOS
NSLayoutManagerconfiguration to avoid font-leading-driven line-metric mismatches and updates text-container sizing to prefer MAUI’sfinalSize. - Adds a HostApp repro page (Issue36505) using a custom STAT font and a tappable Span.
- Adds an Appium UI test to validate that tapping the visually rendered span triggers the recognizer.
Reviewed changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/Controls/src/Core/Platform/iOS/Extensions/FormattedStringExtensions.cs | Updates span-rect calculation to better match rendered text metrics and uses MAUI layout size for container sizing. |
| src/Controls/tests/TestCases.HostApp/MauiProgram.cs | Registers the custom STAT font with the test HostApp. |
| src/Controls/tests/TestCases.HostApp/Issues/Issue36505.cs | Adds the repro UI for the formatted-string span tap hitbox issue. |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue36505.cs | Adds an Appium regression test that taps the expected span location and asserts success. |
| // On iOS 16+, NSLayoutManager's default UsesFontLeading=true causes it to include | ||
| // font leading (extra line spacing) from the OS/2 typographic metrics that CoreText | ||
| // uses when a font has an OpenType STAT table. This makes the layout manager compute | ||
| // line heights that don't match what CoreText uses to draw the glyphs, resulting in | ||
| // span tap hitboxes being vertically offset from the rendered text. | ||
| // Disabling UsesFontLeading on iOS 16+ makes NSLayoutManager match CoreText's metrics | ||
| // so the calculated span rects align with the actual rendered text positions. | ||
| // See: https://github.com/dotnet/maui/issues/36505 | ||
| using var layoutManager = new NSLayoutManager | ||
| { | ||
| UsesFontLeading = !OperatingSystem.IsIOSVersionAtLeast(16) | ||
| }; |
| void TapClickMe(float x, float y, float visualLineHeight, float lineCenterOffset) | ||
| { | ||
| #if MACCATALYST | ||
| App.TapCoordinates(x, y + (visualLineHeight * 15) + lineCenterOffset - visualLineHeight * 0.5f); | ||
| #else | ||
| App.TapCoordinates(x, y + (visualLineHeight * 15) + lineCenterOffset); | ||
| #endif | ||
| } |
The 'Download drop-deep-uitests' step in UpdateAISummaryComment gated on the deep stage's RESULT (runDeepUITestsResult). That cross-stage value is unreliable and has hidden real results twice: - empty via dependencies.RunDeepUITests.result (14651727/#36564), and - spuriously 'Skipped' via stageDependencies.RunDeepUITests.result (14652616/#35156: 9 categories ran and published drop-deep-uitests, but the summary posted 'No UI test results were produced' because the download was skipped -> artDir absent -> review-only summary). Gate the download on the SAME signal the deep stage itself uses to decide whether to run: ReviewPR's detectedCategories output (present and not NONE/ALL). ReviewPR always runs, so that output is dependable across the stage boundary. Now the artifact is downloaded exactly when the deep stage ran and published it, so real results are always surfaced; a genuinely-skipped deep stage still skips the download cleanly (no spurious yellow). continueOnError remains as defense-in-depth. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 15d2af20-e4ab-4e88-9011-cfbd83513bc0
0651f27 to
84d8b21
Compare
…tring when font contains a STAT table (#36564) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details When a Label uses FormattedText with a custom font that has an OpenType STAT table, tapping a Span with a TapGestureRecognizer doesn't work correctly on iOS. The tap hitbox is vertically offset from where the text is actually drawn — tapping the visible text does nothing, tapping below it fires the event. ### Description of Change <!-- Enter description of the fix in this section --> NSLayoutManager.UsesFontLeading is now set to false on iOS 16+ so the tap hitbox calculation uses the same line metrics that CoreText uses to render the text, eliminating the vertical offset. The container size is also updated to use finalSize (MAUI's layout size) instead of control.Bounds, which can be zero/stale during layout on Mac Catalyst. ### Issues Fixed <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #36505 <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. --> **Tested the behavior in the following platforms.** - [ ] Android - [ ] Windows - [x] iOS - [x] Mac | Before | After | |---------|--------| | **iOS**<br> <video src="https://github.com/user-attachments/assets/622bbc78-ea45-48a3-8433-53a6ed2b1ce9" width="300" height="600"> | **iOS**<br> <video src="https://github.com/user-attachments/assets/e42b373b-6d5f-4982-8106-fd4f66ea0aff" width="300" height="600"> |
…tring when font contains a STAT table (#36564) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details When a Label uses FormattedText with a custom font that has an OpenType STAT table, tapping a Span with a TapGestureRecognizer doesn't work correctly on iOS. The tap hitbox is vertically offset from where the text is actually drawn — tapping the visible text does nothing, tapping below it fires the event. ### Description of Change <!-- Enter description of the fix in this section --> NSLayoutManager.UsesFontLeading is now set to false on iOS 16+ so the tap hitbox calculation uses the same line metrics that CoreText uses to render the text, eliminating the vertical offset. The container size is also updated to use finalSize (MAUI's layout size) instead of control.Bounds, which can be zero/stale during layout on Mac Catalyst. ### Issues Fixed <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #36505 <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. --> **Tested the behavior in the following platforms.** - [ ] Android - [ ] Windows - [x] iOS - [x] Mac | Before | After | |---------|--------| | **iOS**<br> <video src="https://github.com/user-attachments/assets/622bbc78-ea45-48a3-8433-53a6ed2b1ce9" width="300" height="600"> | **iOS**<br> <video src="https://github.com/user-attachments/assets/e42b373b-6d5f-4982-8106-fd4f66ea0aff" width="300" height="600"> |
…tring when font contains a STAT table (#36564) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details When a Label uses FormattedText with a custom font that has an OpenType STAT table, tapping a Span with a TapGestureRecognizer doesn't work correctly on iOS. The tap hitbox is vertically offset from where the text is actually drawn — tapping the visible text does nothing, tapping below it fires the event. ### Description of Change <!-- Enter description of the fix in this section --> NSLayoutManager.UsesFontLeading is now set to false on iOS 16+ so the tap hitbox calculation uses the same line metrics that CoreText uses to render the text, eliminating the vertical offset. The container size is also updated to use finalSize (MAUI's layout size) instead of control.Bounds, which can be zero/stale during layout on Mac Catalyst. ### Issues Fixed <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #36505 <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. --> **Tested the behavior in the following platforms.** - [ ] Android - [ ] Windows - [x] iOS - [x] Mac | Before | After | |---------|--------| | **iOS**<br> <video src="https://github.com/user-attachments/assets/622bbc78-ea45-48a3-8433-53a6ed2b1ce9" width="300" height="600"> | **iOS**<br> <video src="https://github.com/user-attachments/assets/e42b373b-6d5f-4982-8106-fd4f66ea0aff" width="300" height="600"> |
…tring when font contains a STAT table (#36564) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details When a Label uses FormattedText with a custom font that has an OpenType STAT table, tapping a Span with a TapGestureRecognizer doesn't work correctly on iOS. The tap hitbox is vertically offset from where the text is actually drawn — tapping the visible text does nothing, tapping below it fires the event. ### Description of Change <!-- Enter description of the fix in this section --> NSLayoutManager.UsesFontLeading is now set to false on iOS 16+ so the tap hitbox calculation uses the same line metrics that CoreText uses to render the text, eliminating the vertical offset. The container size is also updated to use finalSize (MAUI's layout size) instead of control.Bounds, which can be zero/stale during layout on Mac Catalyst. ### Issues Fixed <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #36505 <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. --> **Tested the behavior in the following platforms.** - [ ] Android - [ ] Windows - [x] iOS - [x] Mac | Before | After | |---------|--------| | **iOS**<br> <video src="https://github.com/user-attachments/assets/622bbc78-ea45-48a3-8433-53a6ed2b1ce9" width="300" height="600"> | **iOS**<br> <video src="https://github.com/user-attachments/assets/e42b373b-6d5f-4982-8106-fd4f66ea0aff" width="300" height="600"> |
…tring when font contains a STAT table (#36564) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details When a Label uses FormattedText with a custom font that has an OpenType STAT table, tapping a Span with a TapGestureRecognizer doesn't work correctly on iOS. The tap hitbox is vertically offset from where the text is actually drawn — tapping the visible text does nothing, tapping below it fires the event. ### Description of Change <!-- Enter description of the fix in this section --> NSLayoutManager.UsesFontLeading is now set to false on iOS 16+ so the tap hitbox calculation uses the same line metrics that CoreText uses to render the text, eliminating the vertical offset. The container size is also updated to use finalSize (MAUI's layout size) instead of control.Bounds, which can be zero/stale during layout on Mac Catalyst. ### Issues Fixed <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #36505 <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. --> **Tested the behavior in the following platforms.** - [ ] Android - [ ] Windows - [x] iOS - [x] Mac | Before | After | |---------|--------| | **iOS**<br> <video src="https://github.com/user-attachments/assets/622bbc78-ea45-48a3-8433-53a6ed2b1ce9" width="300" height="600"> | **iOS**<br> <video src="https://github.com/user-attachments/assets/e42b373b-6d5f-4982-8106-fd4f66ea0aff" width="300" height="600"> |
Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Issue Details
When a Label uses FormattedText with a custom font that has an OpenType STAT table, tapping a Span with a TapGestureRecognizer doesn't work correctly on iOS. The tap hitbox is vertically offset from where the text is actually drawn — tapping the visible text does nothing, tapping below it fires the event.
Description of Change
NSLayoutManager.UsesFontLeading is now set to false on iOS 16+ so the tap hitbox calculation uses the same line metrics that CoreText uses to render the text, eliminating the vertical offset. The container size is also updated to use finalSize (MAUI's layout size) instead of control.Bounds, which can be zero/stale during layout on Mac Catalyst.
Issues Fixed
Fixes #36505
Tested the behavior in the following platforms.
Before.mov
After.mov