Skip to content

[iOS] Fix Picker CharacterSpacing lost after item selection when Title is set#34974

Open
SyedAbdulAzeemSF4852 wants to merge 2 commits intodotnet:mainfrom
SyedAbdulAzeemSF4852:fix/picker-charspacing-lost-on-select
Open

[iOS] Fix Picker CharacterSpacing lost after item selection when Title is set#34974
SyedAbdulAzeemSF4852 wants to merge 2 commits intodotnet:mainfrom
SyedAbdulAzeemSF4852:fix/picker-charspacing-lost-on-select

Conversation

@SyedAbdulAzeemSF4852
Copy link
Copy Markdown
Contributor

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 Picker has both a Title and a non-zero CharacterSpacing, the character spacing is silently lost as soon as the user selects an item from the picker, or when SelectedIndex is changed programmatically. The spacing is visible before selection (applied to the placeholder/title text), but after any item is selected, the selected item renders without spacing.

Root Cause

  • Regression: Introduced by PR [iOS] Fixed picker title's color #20205
  • PR [iOS] Fixed picker title's color #20205 changed iOS Picker to apply CharacterSpacing via AttributedPlaceholder so the Title text respects kern. When the user selects an item, the code assigns a plain string to platformPicker.Text. iOS internally creates a zero-kern AttributedText from that plain string and simultaneously hides AttributedPlaceholder, since iOS never shows a placeholder when the text field has a value. This means the kern that was applied to the placeholder is gone, and no kern is applied to the selected item text — resulting in CharacterSpacing being silently lost after selection.

Description of Change

  • After platformPicker.Text is set to the selected item's string, UpdateCharacterSpacing is now explicitly called to re-apply kern to AttributedText. This is done in two places: in UpdatePickerFromPickerSource (the Done-button code path in PickerHandler.iOS.cs) and in UpdatePicker (the programmatic SelectedIndex change path in PickerExtensions.cs), ensuring CharacterSpacing survives item selection regardless of how the selection is triggered.

Issues Fixed

Fixes #34971

Validated the behaviour in the following platforms

  • Windows
  • Android
  • iOS
  • Mac

Output

Before After
Before.mov
After.mov

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 15, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://github.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 34974

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://github.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 34974"

@dotnet-policy-service dotnet-policy-service Bot added community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration labels Apr 15, 2026
@sheiksyedm sheiksyedm marked this pull request as ready for review April 15, 2026 10:57
Copilot AI review requested due to automatic review settings April 15, 2026 10:57
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes an iOS/MacCatalyst regression where Picker.CharacterSpacing is lost after an item is selected when Title is set, by re-applying kerning after the native text is assigned.

Changes:

  • Re-apply CharacterSpacing after platformPicker.Text is set during selection updates (both programmatic and “Done” selection paths).
  • Add an iOS device test to validate CharacterSpacing is preserved across SelectedIndex updates.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/Core/tests/DeviceTests/Handlers/Picker/PickerHandlerTests.iOS.cs Adds a device test asserting character spacing is preserved when SelectedIndex changes programmatically.
src/Core/src/Platform/iOS/PickerExtensions.cs Ensures UpdatePicker always re-applies character spacing after setting Text.
src/Core/src/Handlers/Picker/PickerHandler.iOS.cs Re-applies character spacing after assigning Text in the “Done button” selection flow.

@MauiBot MauiBot added s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-fix-win AI found a better alternative fix than the PR s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Apr 15, 2026
@dotnet dotnet deleted a comment from MauiBot Apr 15, 2026
@dotnet dotnet deleted a comment from MauiBot Apr 15, 2026
Copy link
Copy Markdown
Contributor

@kubaflo kubaflo left a comment

Choose a reason for hiding this comment

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

Could you please try the ai's suggestions?

@dotnet dotnet deleted a comment from MauiBot Apr 23, 2026
@dotnet dotnet deleted a comment from MauiBot Apr 23, 2026
@MauiBot MauiBot added s/agent-approved AI agent recommends approval - PR fix is correct and optimal s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates and removed s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-fix-win AI found a better alternative fix than the PR labels Apr 23, 2026
@dotnet dotnet deleted a comment from MauiBot Apr 23, 2026
@MauiBot MauiBot added s/agent-changes-requested AI agent recommends changes - found a better alternative or issues and removed s/agent-approved AI agent recommends approval - PR fix is correct and optimal labels Apr 24, 2026
@dotnet dotnet deleted a comment from MauiBot Apr 24, 2026
@MauiBot MauiBot added s/agent-fix-win AI found a better alternative fix than the PR and removed s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates labels Apr 24, 2026
@dotnet dotnet deleted a comment from MauiBot Apr 24, 2026
@MauiBot MauiBot added s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates and removed s/agent-fix-win AI found a better alternative fix than the PR labels Apr 24, 2026
@dotnet dotnet deleted a comment from MauiBot Apr 24, 2026
@MauiBot MauiBot added s/agent-fix-win AI found a better alternative fix than the PR and removed s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates labels Apr 24, 2026
@dotnet dotnet deleted a comment from MauiBot Apr 25, 2026
@dotnet dotnet deleted a comment from MauiBot Apr 26, 2026
PureWeen pushed a commit that referenced this pull request Apr 30, 2026
…ability (#35133)

<!-- 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!

> **Depends on #35136** (pipeline category detection — should merge
first)

## What this does

Two things:

### 1. UI test category detection in PR review

During the PR review workflow, Step 0.5 detects which UI test categories
the PR impacts and writes the result to the AI summary comment. This
gives reviewers visibility into which UI tests are relevant.

**Detection** reuses the 3-tier script from #35136 (test attributes →
source paths → AI reasoning).

**AI summary** shows a new 🧪 UI Tests section with detected categories
before the gate section.

### 2. Gate reliability fixes

Multiple fixes to make the gate (`verify-tests-fail.ps1`) more
deterministic:

| Fix | Problem it solves |
|-----|-------------------|
| **Absolute path resolution** | Gate scripts not found on Linux CI
agents (`Resolve-Path`, `GetFullPath`) |
| **File existence check** | Instant cryptic failure when verify script
is missing — now logs clear error |
| **3x retry on ENV ERROR** | Emulator timeouts, ADB failures, app
crashes — transient issues that pass on retry |
| **Strip bad report blocks** | Old verify script produces `Passed:
False` with empty counts — stripped instead of shown |
| **Gate log in fallback** | When report is missing, shows last 20 lines
of gate output instead of just `❌ FAILED / Platform: IOS` |

## Files

| File | Changes |
|------|---------|
| `.github/scripts/Review-PR.ps1` | Step 0.5 category detection + all 5
gate fixes |
| `.github/scripts/post-ai-summary-comment.ps1` | Add `uitests` phase to
render detected categories |
| `.github/pr-review/pr-preflight.md` | Step 7: AI identifies impacted
UI test categories |

## Validation — PR reviewer builds (Apr 26)

10 builds against real PRs — all succeeded ✅. Category detection shown
in AI summary comment.

| PR | Categories Detected | Build | AI Summary |
|----|-------------------|-------|------------|
| #35037 (WebView theme) | `ViewBaseTests,WebView` |
[13940071](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940071)
|
[comment](#35037 (comment))
|
| #35031 (Shell memory leak) | `Shell` |
[13940072](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940072)
|
[comment](#35031 (comment))
|
| #35020 (XAML Hot Reload) | _(none — XAML only)_ |
[13940073](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940073)
| ✅ Shows "No UI test categories" |
| #35008 (Shell SearchHandler) | `Shell` |
[13940074](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940074)
| ✅ |
| #34997 (RadioButton gradient) | `RadioButton,ViewBaseTests` |
[13940075](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940075)
| ✅ |
| #34980 (DatePicker rotation) | `ViewBaseTests` |
[13940076](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940076)
| ✅ |
| #34974 (Picker CharacterSpacing) | `ViewBaseTests` |
[13940077](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940077)
| ✅ |
| #34923 (SwipeView threshold) | `SwipeView,ViewBaseTests` |
[13940078](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940078)
| ✅ |
| #34907 (CollectionView ScrollTo) | `CollectionView` |
[13940079](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940079)
| ✅ |
| #34845 (RefreshView binding) | `RefreshView,ViewBaseTests` |
[13940080](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940080)
| ✅ |

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@dotnet dotnet deleted a comment from MauiBot May 2, 2026
Copy link
Copy Markdown
Collaborator

@MauiBot MauiBot left a comment

Choose a reason for hiding this comment

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

Expert Review — 1 findings

See inline comments for details.

@dotnet dotnet deleted a comment from MauiBot May 3, 2026
@dotnet dotnet deleted a comment from MauiBot May 3, 2026
@MauiBot
Copy link
Copy Markdown
Collaborator

MauiBot commented May 3, 2026

🤖 AI Summary

👋 @SyedAbdulAzeemSF4852 — new AI review results are available. Please review the latest session below.

📊 Review Sessionaa694be · Address review feedback: array initializer + Done-button device test · 2026-05-03 16:11 UTC
🚦 Gate — Test Before & After Fix

Gate Result: ❌ FAILED

Platform: IOS · Base: main · Merge base: 1463c4c5

🩺 Fix does not pass the tests — every test still fails after applying the fix. The PR's change does not resolve the failure(s).

Test Without Fix (expect FAIL) With Fix (expect PASS)
📱 PickerHandlerTests (SelectedIndexDoesNotAffectCharacterSpacing, SelectingItemWithDoneDoesNotAffectCharacterSpacing) Category=Picker ✅ FAIL — 445s ❌ FAIL — 204s
🔴 Without fix — 📱 PickerHandlerTests (SelectedIndexDoesNotAffectCharacterSpacing, SelectingItemWithDoneDoesNotAffectCharacterSpacing): FAIL ✅ · 445s

(truncated to last 15,000 chars)

LoopRunSpecific + 572
�[40m�[37mdbug�[39m�[22m�[49m: frame #7: 0x0000000195484c78 Foundation`-[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 212
�[40m�[37mdbug�[39m�[22m�[49m: frame #8: 0x00000001954f83a4 Foundation`-[NSRunLoop(NSRunLoop) runUntilDate:] + 100
�[40m�[37mdbug�[39m�[22m�[49m: frame #9: 0x00000001008baf28 mlaunch`xamarin_dyn_objc_msgSend + 160
�[40m�[37mdbug�[39m�[22m�[49m: frame #10: 0x0000000103fede14
�[40m�[37mdbug�[39m�[22m�[49m: frame #11: 0x0000000104353468
�[40m�[37mdbug�[39m�[22m�[49m: frame #12: 0x0000000103fe7824
�[40m�[37mdbug�[39m�[22m�[49m: frame #13: 0x0000000103f810b4
�[40m�[37mdbug�[39m�[22m�[49m: frame #14: 0x000000010379cd54
�[40m�[37mdbug�[39m�[22m�[49m: frame #15: 0x0000000102644c04 libcoreclr.dylib`CallDescrWorkerInternal + 132
�[40m�[37mdbug�[39m�[22m�[49m: frame #16: 0x00000001024c2d30 libcoreclr.dylib`MethodDescCallSite::CallTargetWorker(unsigned long long const*, unsigned long long*, int) + 836
�[40m�[37mdbug�[39m�[22m�[49m: frame #17: 0x00000001023c9350 libcoreclr.dylib`RunMain(MethodDesc*, short, int*, PtrArray**) + 648
�[40m�[37mdbug�[39m�[22m�[49m: frame #18: 0x00000001023c9688 libcoreclr.dylib`Assembly::ExecuteMainMethod(PtrArray**, int) + 264
�[40m�[37mdbug�[39m�[22m�[49m: frame #19: 0x00000001023f129c libcoreclr.dylib`CorHost2::ExecuteAssembly(unsigned int, char16_t const*, int, char16_t const**, unsigned int*) + 640
�[40m�[37mdbug�[39m�[22m�[49m: frame #20: 0x00000001023b7650 libcoreclr.dylib`coreclr_execute_assembly + 232
�[40m�[37mdbug�[39m�[22m�[49m: frame #21: 0x00000001008b6140 mlaunch`mono_jit_exec + 204
�[40m�[37mdbug�[39m�[22m�[49m: frame #22: 0x00000001008b9ecc mlaunch`xamarin_main + 884
�[40m�[37mdbug�[39m�[22m�[49m: frame #23: 0x00000001008bb1f4 mlaunch`main + 64
�[40m�[37mdbug�[39m�[22m�[49m: frame #24: 0x0000000193a2ab98 dyld`start + 6076
�[40m�[37mdbug�[39m�[22m�[49m: thread #2
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000193dc6b6c libsystem_pthread.dylib`start_wqthread
�[40m�[37mdbug�[39m�[22m�[49m: thread #3
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000193d8b8b0 libsystem_kernel.dylib`__workq_kernreturn + 8
�[40m�[37mdbug�[39m�[22m�[49m: thread #4
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000193d89c34 libsystem_kernel.dylib`mach_msg2_trap + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x0000000193d9c3a0 libsystem_kernel.dylib`mach_msg2_internal + 76
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x0000000193d92764 libsystem_kernel.dylib`mach_msg_overwrite + 484
�[40m�[37mdbug�[39m�[22m�[49m: frame #3: 0x0000000193d89fa8 libsystem_kernel.dylib`mach_msg + 24
�[40m�[37mdbug�[39m�[22m�[49m: frame #4: 0x00000001023b52f4 libcoreclr.dylib`MachMessage::Receive(unsigned int) + 80
�[40m�[37mdbug�[39m�[22m�[49m: frame #5: 0x00000001023b461c libcoreclr.dylib`SEHExceptionThread(void*) + 164
�[40m�[37mdbug�[39m�[22m�[49m: frame #6: 0x0000000193dcbbc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #5, name = '.NET SynchManager'
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000193d8fd04 libsystem_kernel.dylib`kevent + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x00000001023a9304 libcoreclr.dylib`CorUnix::CPalSynchronizationManager::ReadBytesFromProcessPipe(int, unsigned char*, int) + 484
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x00000001023a89f0 libcoreclr.dylib`CorUnix::CPalSynchronizationManager::WorkerThread(void*) + 164
�[40m�[37mdbug�[39m�[22m�[49m: frame #3: 0x00000001023b20fc libcoreclr.dylib`CorUnix::CPalThread::ThreadEntry(void*) + 364
�[40m�[37mdbug�[39m�[22m�[49m: frame #4: 0x0000000193dcbbc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #6, name = '.NET EventPipe'
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000193d92498 libsystem_kernel.dylib`poll + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x00000001026a4e90 libcoreclr.dylib`ds_ipc_poll(_DiagnosticsIpcPollHandle*, unsigned long, unsigned int, void (*)(char const*, unsigned int)) + 172
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x0000000102752bb0 libcoreclr.dylib`ds_ipc_stream_factory_get_next_available_stream(void (*)(char const*, unsigned int)) + 756
�[40m�[37mdbug�[39m�[22m�[49m: frame #3: 0x0000000102750a68 libcoreclr.dylib`server_thread(void*) + 372
�[40m�[37mdbug�[39m�[22m�[49m: frame #4: 0x00000001023b20fc libcoreclr.dylib`CorUnix::CPalThread::ThreadEntry(void*) + 364
�[40m�[37mdbug�[39m�[22m�[49m: frame #5: 0x0000000193dcbbc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #7, name = '.NET DebugPipe'
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000193d8a678 libsystem_kernel.dylib`__open + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x0000000193d956a4 libsystem_kernel.dylib`open + 64
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x00000001026a5a84 libcoreclr.dylib`TwoWayPipe::WaitForConnection() + 40
�[40m�[37mdbug�[39m�[22m�[49m: frame #3: 0x00000001026a0578 libcoreclr.dylib`DbgTransportSession::TransportWorker() + 232
�[40m�[37mdbug�[39m�[22m�[49m: frame #4: 0x000000010269f5c8 libcoreclr.dylib`DbgTransportSession::TransportWorkerStatic(void*) + 40
�[40m�[37mdbug�[39m�[22m�[49m: frame #5: 0x00000001023b20fc libcoreclr.dylib`CorUnix::CPalThread::ThreadEntry(void*) + 364
�[40m�[37mdbug�[39m�[22m�[49m: frame #6: 0x0000000193dcbbc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #8, name = '.NET Debugger'
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000193d8d3cc libsystem_kernel.dylib`__psynch_cvwait + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x0000000193dcc09c libsystem_pthread.dylib`_pthread_cond_wait + 984
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x00000001023a6f6c libcoreclr.dylib`CorUnix::CPalSynchronizationManager::ThreadNativeWait(CorUnix::_ThreadNativeWaitData*, unsigned int, CorUnix::ThreadWakeupReason*, unsigned int*) + 320
�[40m�[37mdbug�[39m�[22m�[49m: frame #3: 0x00000001023a6bec libcoreclr.dylib`CorUnix::CPalSynchronizationManager::BlockThread(CorUnix::CPalThread*, unsigned int, bool, bool, CorUnix::ThreadWakeupReason*, unsigned int*) + 380
�[40m�[37mdbug�[39m�[22m�[49m: frame #4: 0x00000001023ab0cc libcoreclr.dylib`CorUnix::InternalWaitForMultipleObjectsEx(CorUnix::CPalThread*, unsigned int, void* const*, int, unsigned int, int, int) + 1600
�[40m�[37mdbug�[39m�[22m�[49m: frame #5: 0x000000010269dda8 libcoreclr.dylib`DebuggerRCThread::MainLoop() + 228
�[40m�[37mdbug�[39m�[22m�[49m: frame #6: 0x000000010269dc70 libcoreclr.dylib`DebuggerRCThread::ThreadProc() + 256
�[40m�[37mdbug�[39m�[22m�[49m: frame #7: 0x000000010269da24 libcoreclr.dylib`DebuggerRCThread::ThreadProcStatic(void*) + 56
�[40m�[37mdbug�[39m�[22m�[49m: frame #8: 0x00000001023b20fc libcoreclr.dylib`CorUnix::CPalThread::ThreadEntry(void*) + 364
�[40m�[37mdbug�[39m�[22m�[49m: frame #9: 0x0000000193dcbbc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #9
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000193d8d3cc libsystem_kernel.dylib`__psynch_cvwait + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x0000000193dcc09c libsystem_pthread.dylib`_pthread_cond_wait + 984
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x00000001023a6f6c libcoreclr.dylib`CorUnix::CPalSynchronizationManager::ThreadNativeWait(CorUnix::_ThreadNativeWaitData*, unsigned int, CorUnix::ThreadWakeupReason*, unsigned int*) + 320
�[40m�[37mdbug�[39m�[22m�[49m: frame #3: 0x00000001023a6bec libcoreclr.dylib`CorUnix::CPalSynchronizationManager::BlockThread(CorUnix::CPalThread*, unsigned int, bool, bool, CorUnix::ThreadWakeupReason*, unsigned int*) + 380
�[40m�[37mdbug�[39m�[22m�[49m: frame #4: 0x00000001023ab0cc libcoreclr.dylib`CorUnix::InternalWaitForMultipleObjectsEx(CorUnix::CPalThread*, unsigned int, void* const*, int, unsigned int, int, int) + 1600
�[40m�[37mdbug�[39m�[22m�[49m: frame #5: 0x00000001024f8078 libcoreclr.dylib`FinalizerThread::WaitForFinalizerEvent(CLREvent*) + 240
�[40m�[37mdbug�[39m�[22m�[49m: frame #6: 0x00000001024f81d8 libcoreclr.dylib`FinalizerThread::FinalizerThreadWorker(void*) + 264
�[40m�[37mdbug�[39m�[22m�[49m: frame #7: 0x0000000102495fa8 libcoreclr.dylib`ManagedThreadBase_DispatchOuter(ManagedThreadCallState*) + 248
�[40m�[37mdbug�[39m�[22m�[49m: frame #8: 0x000000010249648c libcoreclr.dylib`ManagedThreadBase::FinalizerBase(void (*)(void*)) + 36
�[40m�[37mdbug�[39m�[22m�[49m: frame #9: 0x00000001024f8350 libcoreclr.dylib`FinalizerThread::FinalizerThreadStart(void*) + 88
�[40m�[37mdbug�[39m�[22m�[49m: frame #10: 0x00000001023b20fc libcoreclr.dylib`CorUnix::CPalThread::ThreadEntry(void*) + 364
�[40m�[37mdbug�[39m�[22m�[49m: frame #11: 0x0000000193dcbbc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #10, name = '.NET SigHandler'
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000193d8a7dc libsystem_kernel.dylib`read + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x0000000100a48e98 libSystem.Native.dylib`SignalHandlerLoop + 96
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x0000000193dcbbc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #11
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000193d8fd04 libsystem_kernel.dylib`kevent + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x0000000100a474a4 libSystem.Native.dylib`SystemNative_WaitForSocketEvents + 80
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x00000001040fca8c
�[40m�[37mdbug�[39m�[22m�[49m: frame #3: 0x00000001040fc7cc
�[40m�[37mdbug�[39m�[22m�[49m: frame #4: 0x00000001040fc3b4
�[40m�[37mdbug�[39m�[22m�[49m: frame #5: 0x0000000103fe1430
�[40m�[37mdbug�[39m�[22m�[49m: frame #6: 0x0000000103fe11e0
�[40m�[37mdbug�[39m�[22m�[49m: frame #7: 0x0000000103fe1108
�[40m�[37mdbug�[39m�[22m�[49m: frame #8: 0x0000000102644c04 libcoreclr.dylib`CallDescrWorkerInternal + 132
�[40m�[37mdbug�[39m�[22m�[49m: frame #9: 0x00000001024c2988 libcoreclr.dylib`DispatchCallSimple(unsigned long*, unsigned int, unsigned long long, unsigned int) + 268
�[40m�[37mdbug�[39m�[22m�[49m: frame #10: 0x00000001024d4c6c libcoreclr.dylib`ThreadNative::KickOffThread_Worker(void*) + 148
�[40m�[37mdbug�[39m�[22m�[49m: frame #11: 0x0000000102495fa8 libcoreclr.dylib`ManagedThreadBase_DispatchOuter(ManagedThreadCallState*) + 248
�[40m�[37mdbug�[39m�[22m�[49m: frame #12: 0x000000010249645c libcoreclr.dylib`ManagedThreadBase::KickOff(void (*)(void*), void*) + 32
�[40m�[37mdbug�[39m�[22m�[49m: frame #13: 0x00000001024d4d44 libcoreclr.dylib`ThreadNative::KickOffThread(void*) + 172
�[40m�[37mdbug�[39m�[22m�[49m: frame #14: 0x00000001023b20fc libcoreclr.dylib`CorUnix::CPalThread::ThreadEntry(void*) + 364
�[40m�[37mdbug�[39m�[22m�[49m: frame #15: 0x0000000193dcbbc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #12
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000193d89c34 libsystem_kernel.dylib`mach_msg2_trap + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x0000000193d9c3a0 libsystem_kernel.dylib`mach_msg2_internal + 76
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x0000000193d92764 libsystem_kernel.dylib`mach_msg_overwrite + 484
�[40m�[37mdbug�[39m�[22m�[49m: frame #3: 0x0000000193d89fa8 libsystem_kernel.dylib`mach_msg + 24
�[40m�[37mdbug�[39m�[22m�[49m: frame #4: 0x0000000193eb6c0c CoreFoundation`__CFRunLoopServiceMachPort + 160
�[40m�[37mdbug�[39m�[22m�[49m: frame #5: 0x0000000193eb5528 CoreFoundation`__CFRunLoopRun + 1208
�[40m�[37mdbug�[39m�[22m�[49m: frame #6: 0x0000000193eb49e8 CoreFoundation`CFRunLoopRunSpecific + 572
�[40m�[37mdbug�[39m�[22m�[49m: frame #7: 0x0000000195484c78 Foundation`-[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 212
�[40m�[37mdbug�[39m�[22m�[49m: frame #8: 0x00000001008baf28 mlaunch`xamarin_dyn_objc_msgSend + 160
�[40m�[37mdbug�[39m�[22m�[49m: frame #9: 0x00000001043489e4
�[40m�[37mdbug�[39m�[22m�[49m: frame #10: 0x00000001043488a8
�[40m�[37mdbug�[39m�[22m�[49m: frame #11: 0x00000001043486dc
�[40m�[37mdbug�[39m�[22m�[49m: frame #12: 0x0000000104345660
�[40m�[37mdbug�[39m�[22m�[49m: frame #13: 0x0000000103fe13d8
�[40m�[37mdbug�[39m�[22m�[49m: frame #14: 0x0000000103fe11e0
�[40m�[37mdbug�[39m�[22m�[49m: frame #15: 0x0000000103fe1108
�[40m�[37mdbug�[39m�[22m�[49m: frame #16: 0x0000000102644c04 libcoreclr.dylib`CallDescrWorkerInternal + 132
�[40m�[37mdbug�[39m�[22m�[49m: frame #17: 0x00000001024c2988 libcoreclr.dylib`DispatchCallSimple(unsigned long*, unsigned int, unsigned long long, unsigned int) + 268
�[40m�[37mdbug�[39m�[22m�[49m: frame #18: 0x00000001024d4c6c libcoreclr.dylib`ThreadNative::KickOffThread_Worker(void*) + 148
�[40m�[37mdbug�[39m�[22m�[49m: frame #19: 0x0000000102495fa8 libcoreclr.dylib`ManagedThreadBase_DispatchOuter(ManagedThreadCallState*) + 248
�[40m�[37mdbug�[39m�[22m�[49m: frame #20: 0x000000010249645c libcoreclr.dylib`ManagedThreadBase::KickOff(void (*)(void*), void*) + 32
�[40m�[37mdbug�[39m�[22m�[49m: frame #21: 0x00000001024d4d44 libcoreclr.dylib`ThreadNative::KickOffThread(void*) + 172
�[40m�[37mdbug�[39m�[22m�[49m: frame #22: 0x00000001023b20fc libcoreclr.dylib`CorUnix::CPalThread::ThreadEntry(void*) + 364
�[40m�[37mdbug�[39m�[22m�[49m: frame #23: 0x0000000193dcbbc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #13, name = 'com.apple.CFSocket.private'
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000193d94c2c libsystem_kernel.dylib`__select + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x0000000193edca80 CoreFoundation`__CFSocketManager + 704
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x0000000193dcbbc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #14
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000000000000
�[40m�[37mdbug�[39m�[22m�[49m: (lldb) detach
�[40m�[37mdbug�[39m�[22m�[49m: Process 9393 detached
�[40m�[37mdbug�[39m�[22m�[49m: (lldb) quit
�[40m�[37mdbug�[39m�[22m�[49m: 9393 Execution timed out after 60 seconds and the process was killed.
�[40m�[37mdbug�[39m�[22m�[49m: Process mlaunch exited with 137
�[40m�[37mdbug�[39m�[22m�[49m: Failed to list crash reports from device.
�[40m�[37mdbug�[39m�[22m�[49m: Test run started but crashed and no test results were reported
�[40m�[37mdbug�[39m�[22m�[49m: No crash reports, waiting 30 seconds for the crash report service...
�[41m�[30mfail�[39m�[22m�[49m: Application test run crashed
      Failed to launch the application, please try again. If the problem persists, try rebooting MacOS
�[40m�[32minfo�[39m�[22m�[49m: Uninstalling the application 'com.microsoft.maui.core.devicetests' from 'iPhone 11 Pro'
�[40m�[37mdbug�[39m�[22m�[49m: 
�[40m�[37mdbug�[39m�[22m�[49m: Running /Applications/Xcode_26.1.1.app/Contents/Developer/usr/bin/simctl
�[40m�[37mdbug�[39m�[22m�[49m: An error was encountered processing the command (domain=com.apple.CoreSimulator.SimError, code=405):
�[40m�[37mdbug�[39m�[22m�[49m: Unable to lookup in current state: Shutdown
�[40m�[37mdbug�[39m�[22m�[49m: Process simctl exited with 149
�[41m�[30mfail�[39m�[22m�[49m: Failed to uninstall the app bundle! Check logs for more details!
XHarness exit code: 83 (APP_LAUNCH_FAILURE)
  Passed: 0
  Failed: 0
  Tests completed with exit code: 83

🟢 With fix — 📱 PickerHandlerTests (SelectedIndexDoesNotAffectCharacterSpacing, SelectingItemWithDoneDoesNotAffectCharacterSpacing): FAIL ❌ · 204s

(truncated to last 15,000 chars)


�[40m�[37mdbug�[39m�[22m�[49m: frame #14: 0x000000010529cd54
�[40m�[37mdbug�[39m�[22m�[49m: frame #15: 0x00000001041a0c04 libcoreclr.dylib`CallDescrWorkerInternal + 132
�[40m�[37mdbug�[39m�[22m�[49m: frame #16: 0x000000010401ed30 libcoreclr.dylib`MethodDescCallSite::CallTargetWorker(unsigned long long const*, unsigned long long*, int) + 836
�[40m�[37mdbug�[39m�[22m�[49m: frame #17: 0x0000000103f25350 libcoreclr.dylib`RunMain(MethodDesc*, short, int*, PtrArray**) + 648
�[40m�[37mdbug�[39m�[22m�[49m: frame #18: 0x0000000103f25688 libcoreclr.dylib`Assembly::ExecuteMainMethod(PtrArray**, int) + 264
�[40m�[37mdbug�[39m�[22m�[49m: frame #19: 0x0000000103f4d29c libcoreclr.dylib`CorHost2::ExecuteAssembly(unsigned int, char16_t const*, int, char16_t const**, unsigned int*) + 640
�[40m�[37mdbug�[39m�[22m�[49m: frame #20: 0x0000000103f13650 libcoreclr.dylib`coreclr_execute_assembly + 232
�[40m�[37mdbug�[39m�[22m�[49m: frame #21: 0x0000000102506140 mlaunch`mono_jit_exec + 204
�[40m�[37mdbug�[39m�[22m�[49m: frame #22: 0x0000000102509ecc mlaunch`xamarin_main + 884
�[40m�[37mdbug�[39m�[22m�[49m: frame #23: 0x000000010250b1f4 mlaunch`main + 64
�[40m�[37mdbug�[39m�[22m�[49m: frame #24: 0x0000000193a2ab98 dyld`start + 6076
�[40m�[37mdbug�[39m�[22m�[49m: thread #2
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000193d8b8b0 libsystem_kernel.dylib`__workq_kernreturn + 8
�[40m�[37mdbug�[39m�[22m�[49m: thread #3
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000193d89c34 libsystem_kernel.dylib`mach_msg2_trap + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x0000000193d9c3a0 libsystem_kernel.dylib`mach_msg2_internal + 76
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x0000000193d92764 libsystem_kernel.dylib`mach_msg_overwrite + 484
�[40m�[37mdbug�[39m�[22m�[49m: frame #3: 0x0000000193d89fa8 libsystem_kernel.dylib`mach_msg + 24
�[40m�[37mdbug�[39m�[22m�[49m: frame #4: 0x0000000103f112f4 libcoreclr.dylib`MachMessage::Receive(unsigned int) + 80
�[40m�[37mdbug�[39m�[22m�[49m: frame #5: 0x0000000103f1061c libcoreclr.dylib`SEHExceptionThread(void*) + 164
�[40m�[37mdbug�[39m�[22m�[49m: frame #6: 0x0000000193dcbbc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #4, name = '.NET SynchManager'
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000193d8fd04 libsystem_kernel.dylib`kevent + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x0000000103f05304 libcoreclr.dylib`CorUnix::CPalSynchronizationManager::ReadBytesFromProcessPipe(int, unsigned char*, int) + 484
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x0000000103f049f0 libcoreclr.dylib`CorUnix::CPalSynchronizationManager::WorkerThread(void*) + 164
�[40m�[37mdbug�[39m�[22m�[49m: frame #3: 0x0000000103f0e0fc libcoreclr.dylib`CorUnix::CPalThread::ThreadEntry(void*) + 364
�[40m�[37mdbug�[39m�[22m�[49m: frame #4: 0x0000000193dcbbc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #5, name = '.NET EventPipe'
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000193d92498 libsystem_kernel.dylib`poll + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x0000000104200e90 libcoreclr.dylib`ds_ipc_poll(_DiagnosticsIpcPollHandle*, unsigned long, unsigned int, void (*)(char const*, unsigned int)) + 172
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x00000001042aebb0 libcoreclr.dylib`ds_ipc_stream_factory_get_next_available_stream(void (*)(char const*, unsigned int)) + 756
�[40m�[37mdbug�[39m�[22m�[49m: frame #3: 0x00000001042aca68 libcoreclr.dylib`server_thread(void*) + 372
�[40m�[37mdbug�[39m�[22m�[49m: frame #4: 0x0000000103f0e0fc libcoreclr.dylib`CorUnix::CPalThread::ThreadEntry(void*) + 364
�[40m�[37mdbug�[39m�[22m�[49m: frame #5: 0x0000000193dcbbc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #6, name = '.NET DebugPipe'
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000193d8a678 libsystem_kernel.dylib`__open + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x0000000193d956a4 libsystem_kernel.dylib`open + 64
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x0000000104201a84 libcoreclr.dylib`TwoWayPipe::WaitForConnection() + 40
�[40m�[37mdbug�[39m�[22m�[49m: frame #3: 0x00000001041fc578 libcoreclr.dylib`DbgTransportSession::TransportWorker() + 232
�[40m�[37mdbug�[39m�[22m�[49m: frame #4: 0x00000001041fb5c8 libcoreclr.dylib`DbgTransportSession::TransportWorkerStatic(void*) + 40
�[40m�[37mdbug�[39m�[22m�[49m: frame #5: 0x0000000103f0e0fc libcoreclr.dylib`CorUnix::CPalThread::ThreadEntry(void*) + 364
�[40m�[37mdbug�[39m�[22m�[49m: frame #6: 0x0000000193dcbbc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #7, name = '.NET Debugger'
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000193d8d3cc libsystem_kernel.dylib`__psynch_cvwait + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x0000000193dcc09c libsystem_pthread.dylib`_pthread_cond_wait + 984
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x0000000103f02f6c libcoreclr.dylib`CorUnix::CPalSynchronizationManager::ThreadNativeWait(CorUnix::_ThreadNativeWaitData*, unsigned int, CorUnix::ThreadWakeupReason*, unsigned int*) + 320
�[40m�[37mdbug�[39m�[22m�[49m: frame #3: 0x0000000103f02bec libcoreclr.dylib`CorUnix::CPalSynchronizationManager::BlockThread(CorUnix::CPalThread*, unsigned int, bool, bool, CorUnix::ThreadWakeupReason*, unsigned int*) + 380
�[40m�[37mdbug�[39m�[22m�[49m: frame #4: 0x0000000103f070cc libcoreclr.dylib`CorUnix::InternalWaitForMultipleObjectsEx(CorUnix::CPalThread*, unsigned int, void* const*, int, unsigned int, int, int) + 1600
�[40m�[37mdbug�[39m�[22m�[49m: frame #5: 0x00000001041f9da8 libcoreclr.dylib`DebuggerRCThread::MainLoop() + 228
�[40m�[37mdbug�[39m�[22m�[49m: frame #6: 0x00000001041f9c70 libcoreclr.dylib`DebuggerRCThread::ThreadProc() + 256
�[40m�[37mdbug�[39m�[22m�[49m: frame #7: 0x00000001041f9a24 libcoreclr.dylib`DebuggerRCThread::ThreadProcStatic(void*) + 56
�[40m�[37mdbug�[39m�[22m�[49m: frame #8: 0x0000000103f0e0fc libcoreclr.dylib`CorUnix::CPalThread::ThreadEntry(void*) + 364
�[40m�[37mdbug�[39m�[22m�[49m: frame #9: 0x0000000193dcbbc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #8
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000193d8d3cc libsystem_kernel.dylib`__psynch_cvwait + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x0000000193dcc09c libsystem_pthread.dylib`_pthread_cond_wait + 984
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x0000000103f02f6c libcoreclr.dylib`CorUnix::CPalSynchronizationManager::ThreadNativeWait(CorUnix::_ThreadNativeWaitData*, unsigned int, CorUnix::ThreadWakeupReason*, unsigned int*) + 320
�[40m�[37mdbug�[39m�[22m�[49m: frame #3: 0x0000000103f02bec libcoreclr.dylib`CorUnix::CPalSynchronizationManager::BlockThread(CorUnix::CPalThread*, unsigned int, bool, bool, CorUnix::ThreadWakeupReason*, unsigned int*) + 380
�[40m�[37mdbug�[39m�[22m�[49m: frame #4: 0x0000000103f070cc libcoreclr.dylib`CorUnix::InternalWaitForMultipleObjectsEx(CorUnix::CPalThread*, unsigned int, void* const*, int, unsigned int, int, int) + 1600
�[40m�[37mdbug�[39m�[22m�[49m: frame #5: 0x0000000104054078 libcoreclr.dylib`FinalizerThread::WaitForFinalizerEvent(CLREvent*) + 240
�[40m�[37mdbug�[39m�[22m�[49m: frame #6: 0x00000001040541d8 libcoreclr.dylib`FinalizerThread::FinalizerThreadWorker(void*) + 264
�[40m�[37mdbug�[39m�[22m�[49m: frame #7: 0x0000000103ff1fa8 libcoreclr.dylib`ManagedThreadBase_DispatchOuter(ManagedThreadCallState*) + 248
�[40m�[37mdbug�[39m�[22m�[49m: frame #8: 0x0000000103ff248c libcoreclr.dylib`ManagedThreadBase::FinalizerBase(void (*)(void*)) + 36
�[40m�[37mdbug�[39m�[22m�[49m: frame #9: 0x0000000104054350 libcoreclr.dylib`FinalizerThread::FinalizerThreadStart(void*) + 88
�[40m�[37mdbug�[39m�[22m�[49m: frame #10: 0x0000000103f0e0fc libcoreclr.dylib`CorUnix::CPalThread::ThreadEntry(void*) + 364
�[40m�[37mdbug�[39m�[22m�[49m: frame #11: 0x0000000193dcbbc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #9, name = '.NET SigHandler'
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000193d8a7dc libsystem_kernel.dylib`read + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x00000001025c4e98 libSystem.Native.dylib`SignalHandlerLoop + 96
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x0000000193dcbbc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #10
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000193d8fd04 libsystem_kernel.dylib`kevent + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x00000001025c34a4 libSystem.Native.dylib`SystemNative_WaitForSocketEvents + 80
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x0000000105bfca9c
�[40m�[37mdbug�[39m�[22m�[49m: frame #3: 0x0000000105bfc6f4
�[40m�[37mdbug�[39m�[22m�[49m: frame #4: 0x0000000105bfc43c
�[40m�[37mdbug�[39m�[22m�[49m: frame #5: 0x0000000105ae14c0
�[40m�[37mdbug�[39m�[22m�[49m: frame #6: 0x0000000105ae1218
�[40m�[37mdbug�[39m�[22m�[49m: frame #7: 0x0000000105ae1140
�[40m�[37mdbug�[39m�[22m�[49m: frame #8: 0x00000001041a0c04 libcoreclr.dylib`CallDescrWorkerInternal + 132
�[40m�[37mdbug�[39m�[22m�[49m: frame #9: 0x000000010401e988 libcoreclr.dylib`DispatchCallSimple(unsigned long*, unsigned int, unsigned long long, unsigned int) + 268
�[40m�[37mdbug�[39m�[22m�[49m: frame #10: 0x0000000104030c6c libcoreclr.dylib`ThreadNative::KickOffThread_Worker(void*) + 148
�[40m�[37mdbug�[39m�[22m�[49m: frame #11: 0x0000000103ff1fa8 libcoreclr.dylib`ManagedThreadBase_DispatchOuter(ManagedThreadCallState*) + 248
�[40m�[37mdbug�[39m�[22m�[49m: frame #12: 0x0000000103ff245c libcoreclr.dylib`ManagedThreadBase::KickOff(void (*)(void*), void*) + 32
�[40m�[37mdbug�[39m�[22m�[49m: frame #13: 0x0000000104030d44 libcoreclr.dylib`ThreadNative::KickOffThread(void*) + 172
�[40m�[37mdbug�[39m�[22m�[49m: frame #14: 0x0000000103f0e0fc libcoreclr.dylib`CorUnix::CPalThread::ThreadEntry(void*) + 364
�[40m�[37mdbug�[39m�[22m�[49m: frame #15: 0x0000000193dcbbc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #11
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000193d89c34 libsystem_kernel.dylib`mach_msg2_trap + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x0000000193d9c3a0 libsystem_kernel.dylib`mach_msg2_internal + 76
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x0000000193d92764 libsystem_kernel.dylib`mach_msg_overwrite + 484
�[40m�[37mdbug�[39m�[22m�[49m: frame #3: 0x0000000193d89fa8 libsystem_kernel.dylib`mach_msg + 24
�[40m�[37mdbug�[39m�[22m�[49m: frame #4: 0x0000000193eb6c0c CoreFoundation`__CFRunLoopServiceMachPort + 160
�[40m�[37mdbug�[39m�[22m�[49m: frame #5: 0x0000000193eb5528 CoreFoundation`__CFRunLoopRun + 1208
�[40m�[37mdbug�[39m�[22m�[49m: frame #6: 0x0000000193eb49e8 CoreFoundation`CFRunLoopRunSpecific + 572
�[40m�[37mdbug�[39m�[22m�[49m: frame #7: 0x0000000195484c78 Foundation`-[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 212
�[40m�[37mdbug�[39m�[22m�[49m: frame #8: 0x000000010250af28 mlaunch`xamarin_dyn_objc_msgSend + 160
�[40m�[37mdbug�[39m�[22m�[49m: frame #9: 0x0000000105c49bd4
�[40m�[37mdbug�[39m�[22m�[49m: frame #10: 0x0000000105c49a98
�[40m�[37mdbug�[39m�[22m�[49m: frame #11: 0x0000000105c498cc
�[40m�[37mdbug�[39m�[22m�[49m: frame #12: 0x0000000105c464c8
�[40m�[37mdbug�[39m�[22m�[49m: frame #13: 0x0000000105ae1468
�[40m�[37mdbug�[39m�[22m�[49m: frame #14: 0x0000000105ae1218
�[40m�[37mdbug�[39m�[22m�[49m: frame #15: 0x0000000105ae1140
�[40m�[37mdbug�[39m�[22m�[49m: frame #16: 0x00000001041a0c04 libcoreclr.dylib`CallDescrWorkerInternal + 132
�[40m�[37mdbug�[39m�[22m�[49m: frame #17: 0x000000010401e988 libcoreclr.dylib`DispatchCallSimple(unsigned long*, unsigned int, unsigned long long, unsigned int) + 268
�[40m�[37mdbug�[39m�[22m�[49m: frame #18: 0x0000000104030c6c libcoreclr.dylib`ThreadNative::KickOffThread_Worker(void*) + 148
�[40m�[37mdbug�[39m�[22m�[49m: frame #19: 0x0000000103ff1fa8 libcoreclr.dylib`ManagedThreadBase_DispatchOuter(ManagedThreadCallState*) + 248
�[40m�[37mdbug�[39m�[22m�[49m: frame #20: 0x0000000103ff245c libcoreclr.dylib`ManagedThreadBase::KickOff(void (*)(void*), void*) + 32
�[40m�[37mdbug�[39m�[22m�[49m: frame #21: 0x0000000104030d44 libcoreclr.dylib`ThreadNative::KickOffThread(void*) + 172
�[40m�[37mdbug�[39m�[22m�[49m: frame #22: 0x0000000103f0e0fc libcoreclr.dylib`CorUnix::CPalThread::ThreadEntry(void*) + 364
�[40m�[37mdbug�[39m�[22m�[49m: frame #23: 0x0000000193dcbbc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #12
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000193d8b8b0 libsystem_kernel.dylib`__workq_kernreturn + 8
�[40m�[37mdbug�[39m�[22m�[49m: thread #13, name = 'com.apple.CFSocket.private'
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000193d94c2c libsystem_kernel.dylib`__select + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x0000000193edca80 CoreFoundation`__CFSocketManager + 704
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x0000000193dcbbc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: (lldb) detach
�[40m�[37mdbug�[39m�[22m�[49m: Process 10711 detached
�[40m�[37mdbug�[39m�[22m�[49m: (lldb) quit
�[40m�[37mdbug�[39m�[22m�[49m: 10711 Execution timed out after 60 seconds and the process was killed.
�[40m�[37mdbug�[39m�[22m�[49m: Failed to get ExitCode: System.InvalidOperationException: Process must exit before requested information can be determined.
         at System.Diagnostics.Process.EnsureState(State state)
         at System.Diagnostics.Process.get_ExitCode()
         at Microsoft.DotNet.XHarness.Common.Execution.ProcessManager.RunAsyncInternal(Process process, ILog log, ILog stdout, ILog stderr, Action`2 kill, Func`3 getChildProcessIds, Nullable`1 timeout, Dictionary`2 environmentVariables, Nullable`1 cancellationToken, Nullable`1 diagnostics) in /_/src/Microsoft.DotNet.XHarness.Common/Execution/ProcessManager.cs:line 359
�[40m�[37mdbug�[39m�[22m�[49m: Failed to list crash reports from device.
�[40m�[37mdbug�[39m�[22m�[49m: Test run started but crashed and no test results were reported
�[40m�[37mdbug�[39m�[22m�[49m: No crash reports, waiting 30 seconds for the crash report service...
�[40m�[37mdbug�[39m�[22m�[49m: Found 1 new crash report(s)
�[40m�[37mdbug�[39m�[22m�[49m: - Adding /Users/cloudtest/Library/Logs/DiagnosticReports/Microsoft.Maui.Core.DeviceTests-2026-05-03-060520.ips
�[40m�[37mdbug�[39m�[22m�[49m: Successfully copied Microsoft.Maui.Core.DeviceTests-2026-05-03-060520.ips
�[41m�[30mfail�[39m�[22m�[49m: Application test run crashed
      Failed to launch the application, please try again. If the problem persists, try rebooting MacOS
�[40m�[32minfo�[39m�[22m�[49m: Uninstalling the application 'com.microsoft.maui.core.devicetests' from 'iPhone 11 Pro'
�[40m�[37mdbug�[39m�[22m�[49m: 
�[40m�[37mdbug�[39m�[22m�[49m: Running /Applications/Xcode_26.1.1.app/Contents/Developer/usr/bin/simctl
�[40m�[37mdbug�[39m�[22m�[49m: Process simctl exited with 0
�[40m�[32minfo�[39m�[22m�[49m: Application 'com.microsoft.maui.core.devicetests' was uninstalled successfully
XHarness exit code: 83 (APP_LAUNCH_FAILURE)
  Passed: 40
  Failed: 8
  Tests completed with exit code: 83

⚠️ Failure Details

  • PickerHandlerTests (SelectedIndexDoesNotAffectCharacterSpacing, SelectingItemWithDoneDoesNotAffectCharacterSpacing) FAILED with fix (should pass)
    • Device tests: 8 of 48 failed
📁 Fix files reverted (3 files)
  • eng/pipelines/ci-copilot.yml
  • src/Core/src/Handlers/Picker/PickerHandler.iOS.cs
  • src/Core/src/Platform/iOS/PickerExtensions.cs

🧪 UI Tests — Category Detection

Detected UI test categories: ViewBaseTests


🔍 Regression Cross-Reference

🔍 Regression Cross-Reference

🟢 No regression risks detected. No labeled bug-fix PRs in the last 6 months touched the modified files.


🔍 Pre-Flight — Context & Validation

Issue: #34971 - [iOS] Picker loses CharacterSpacing after item selection when Title is set
PR: #34974 - [iOS] Fix Picker CharacterSpacing lost after item selection when Title is set
Platforms Affected: iOS, MacCatalyst
Files Changed: 2 implementation, 1 test

Key Findings

  • Regression introduced by PR [iOS] Fixed picker title's color #20205: iOS Picker applies CharacterSpacing via AttributedPlaceholder for title text. When the user selects an item, platformPicker.Text = selectedItem assigns a plain string, which causes iOS to internally create a kern-free NSAttributedString, discarding the kern that was set on the placeholder.
  • Fix adds UpdateCharacterSpacing call after text assignment in two code paths: UpdatePickerFromPickerSource (Done-button path) and PickerExtensions.UpdatePicker (programmatic SelectedIndex path).
  • Gate ❌ FAILED — the new device tests did not pass as expected.
  • Two inline review comments were resolved: using array initializer instead of List<string> and adding the "Done button" test path.
  • SelectingItemWithDoneDoesNotAffectCharacterSpacing test (.iOS.cs) accesses UIPickerView and InputAccessoryView which are null/unset on MacCatalyst — will throw NullReferenceException on MacCatalyst builds.

Code Review Summary

Verdict: NEEDS_CHANGES
Confidence: High
Errors: 0 | Warnings: 1 | Suggestions: 1

Key code review findings:

  • ⚠️ src/Core/tests/DeviceTests/Handlers/Picker/PickerHandlerTests.iOS.cs:96SelectingItemWithDoneDoesNotAffectCharacterSpacing accesses mauiPicker.UIPickerView (null on MacCatalyst) and TapDoneOnInputAccessoryView asserts a non-null UIToolbar InputAccessoryView (never set on MacCatalyst). File compiles for both iOS and MacCatalyst — wrap with #if !MACCATALYST.
  • 💡 src/Core/src/Handlers/Picker/PickerHandler.iOS.cs:428OnEditing handler also sets platformView.Text without re-applying CharacterSpacing (pre-existing gap, not introduced by this PR).

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #34974 Call UpdateCharacterSpacing after platformPicker.Text assignment in two code paths ❌ FAILED (Gate) PickerHandler.iOS.cs, PickerExtensions.cs, PickerHandlerTests.iOS.cs Gate failed; MacCatalyst test crash likely

🔬 Code Review — Deep Analysis

Code Review — PR #34974

Independent Assessment

What this changes: Two UpdateCharacterSpacing calls are added at points where a plain-string assignment to UITextField.Text previously erased NSAttributedString kern attributes. One call is in UpdatePickerFromPickerSource (the Done-button path in PickerHandler.iOS.cs) and one in PickerExtensions.UpdatePicker (the programmatic SelectedIndex change path).

Inferred motivation: iOS's UITextField internally constructs a new, kern-free NSAttributedString whenever a plain string is assigned to .Text. If CharacterSpacing was previously applied via AttributedPlaceholder (for the title), that kern is lost the moment the user selects an item. Re-calling UpdateCharacterSpacing immediately after the text assignment restores the kern attribute on the resulting AttributedText.

Is the approach sound? Yes — UpdateCharacterSpacing (TextFieldExtensions.cs:131) is idempotent, null-safe (bails out if AttributedText is null), and also re-applies kern to AttributedPlaceholder, so the no-selection (selectedIndex == -1) path is correctly covered too. The approach is identical to how DatePickerExtensions and TimePickerExtensions already handle the same issue.


Reconciliation with PR Narrative

Author claims: Regression from PR #20205 caused CharacterSpacing to be silently lost after selection; fix adds UpdateCharacterSpacing in two code paths.

Agreement: Full agreement. The root cause analysis is accurate. The two fix locations match the code paths I identified from first principles.


Findings

⚠️ Warning — SelectingItemWithDoneDoesNotAffectCharacterSpacing test crashes on MacCatalyst

PickerHandlerTests.iOS.cs uses the .iOS.cs extension which compiles for both iOS and MacCatalyst. The new test at line 96 directly accesses:

var pickerView = mauiPicker.UIPickerView;      // null on MacCatalyst — CreatePlatformView passes null
var model = (PickerSource)pickerView.Model;    // NullReferenceException on MacCatalyst

And TapDoneOnInputAccessoryView asserts InputAccessoryView is a non-null UIToolbar — but InputAccessoryView is never set in the #if MACCATALYST branch of CreatePlatformView.

The established convention for this exact scenario is a file-level #if !MACCATALYST guard — both TimePickerHandlerTests.iOS.cs and DatePickerHandlerTests.iOS.cs begin with exactly this guard. The simplest fix is to wrap the affected test and helper with #if !MACCATALYST:

#if !MACCATALYST
[Theory(DisplayName = "Selecting An Item With Done Keeps CharacterSpacing")]
...
public async Task SelectingItemWithDoneDoesNotAffectCharacterSpacing(...) { ... }

void TapDoneOnInputAccessoryView(MauiPicker mauiPicker) { ... }
#endif

Note: SelectedIndexDoesNotAffectCharacterSpacing (the other new test, line 67) does not access UIPickerView directly and uses only null-safe calls through MapSelectedIndex → UpdatePicker, so it is MacCatalyst-safe and needs no guard.


💡 Suggestion — OnEditing is a remaining kern gap (pre-existing, not introduced by this PR)

MauiPickerProxy.OnEditing (line 428 in handler file) also does platformView.Text = virtualView.GetItem(selectedIndex) without re-applying character spacing. This is the EditingChanged handler whose purpose is to prevent actual keyboard input from sticking. It's pre-existing and wouldn't be triggered in normal picker usage, but if it ever fires (e.g., on a device with an unexpected hardware keyboard), kern would be temporarily lost until the next mapper call. Consider adding platformView.UpdateCharacterSpacing(virtualView) there as well for completeness.


Devil's Advocate

  • Could the double UpdateCharacterSpacing call in UpdatePicker cause a performance issue? No — it's two NSAttributedString attribute reads/writes on the main thread during a user-initiated selection. Negligible.
  • Could the fix cause a regression when CharacterSpacing is 0 (the default)? No — WithCharacterSpacing(0) removes the kern attribute (equivalent to not having one), so default-spacing pickers are unaffected.
  • Could UpdateCharacterSpacing cause problems when AttributedText is null (no item selected)? No — the null-conditional textField.AttributedText?.WithCharacterSpacing(...) returns null and the assignment is skipped; the placeholder path still works correctly.
  • Is the MacCatalyst production code path (FinishSelectItemUpdatePickerFromPickerSource) covered? Yes, the fix is in shared non-guarded code, so both iOS and MacCatalyst benefit.

Verdict: NEEDS_CHANGES

Confidence: High
Summary: The production fix is correct, minimal, and consistent with established patterns in the codebase. However, SelectingItemWithDoneDoesNotAffectCharacterSpacing will crash with a NullReferenceException on MacCatalyst because .iOS.cs files compile for both targets and the test accesses UIPickerView and InputAccessoryView which are only set on iOS. A #if !MACCATALYST guard around that test and its helper is all that's needed before merge.


🔧 Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 try-fix-1 (claude-opus-4.6) helper atomically constructs NSAttributedString with KerningAdjustment; covers UpdatePicker + UpdatePickerFromPickerSource + OnEditing PASS PickerExtensions.cs, PickerHandler.iOS.cs Fixes OnEditing gap too
2 try-fix-2 (claude-sonnet-4.6) MauiPicker stores CharacterSpacing internally; re-applies kern after Text assignment at two callsites PASS PickerHandler.iOS.cs, PickerExtensions.cs Avoids virtual view traversal
3 try-fix-3 (gpt-5.3-codex) Mapper-ordering: route selection through MapSelectedIndex then call FAIL PickerHandler.iOS.cs, PickerHandlerTests.iOS.cs APP_LAUNCH_FAILURE on final iteration MapCharacterSpacing
4 try-fix-4 (gemini/sonnet) via direct AttributedText assignment (bypasses Text setter entirely when CharacterSpacing != 0); covers all 3 paths PASS PickerExtensions.cs, PickerHandler.iOS.cs Most direct avoids read-modify-write unreliability
PR PR #34974 Call UpdateCharacterSpacing after Text assignment in UpdatePickerFromPickerSource + FAILED (Gate) PickerHandler.iOS.cs, PickerExtensions.cs, PickerHandlerTests.iOS.cs Gate failed; MacCatalyst test crash UpdatePicker

Cross-Pollination

Model Round New Ideas? Details
claude-opus-4.6 2 NO NEW IDEAS Try-fix-1 covers the atomic NSAttributedString approach fully
claude-sonnet-4.6 2 NO NEW IDEAS Try-fix-2 covers the cached CharacterSpacing approach fully
gpt-5.3-codex 2 NO NEW IDEAS Try-fix-3 exhausted mapper-ordering; no new viable angle
gemini/sonnet 2 NO NEW IDEAS Try-fix-4 covers direct AttributedText assignment fully

Exhausted: Yes
Selected Fix: pr-plus- PR's production fix is correct; adding #if !MACCATALYSTguard fixes the MacCatalyst test crash. Alternativelytry-fix-1ortry-fix-4 provide a more robust atomic fix that also covers the OnEditing gap.reviewer


📋 Report — Final Recommendation

⚠️ Final Recommendation: REQUEST CHANGES

Phase Status

Phase Status Notes
Pre-Flight ✅ COMPLETE Issue #34971 — iOS Picker CharacterSpacing lost after item selection
Code Review NEEDS_CHANGES (high) 0 errors, 1 warning, 1 suggestion — MacCatalyst test crash
Gate ❌ FAILED ios — tests did not behave as expected
Try-Fix ✅ COMPLETE 4 attempts: 3 passing (try-fix-1, 2, 4), 1 failing (try-fix-3)
Report ✅ COMPLETE

Code Review Impact on Try-Fix

The code review ⚠️ Warning about SelectingItemWithDoneDoesNotAffectCharacterSpacing crashing on MacCatalyst (.iOS.cs compiles for both platforms, UIPickerView is null on MacCatalyst) was included as a hint to all four try-fix models. Try-fix-4 explicitly addressed this by adding #if !MACCATALYST guards. The OnEditing gap identified in the code review was addressed by try-fix-1 and try-fix-4, which covered all three text-assignment paths. The code review verdict (NEEDS_CHANGES) triggered the hard gate — REQUEST CHANGES recommendation is required regardless of try-fix results.

Summary

The PR's production logic is correct — calling UpdateCharacterSpacing after plain text assignment is sound. However, the Gate ❌ FAILED and code review found a MacCatalyst test crash (SelectingItemWithDoneDoesNotAffectCharacterSpacing dereferences null UIPickerView on MacCatalyst). Try-fix exploration identified a more robust alternative (try-fix-1) that atomically constructs NSAttributedString with KerningAdjustment, covering all three text-assignment paths (including the OnEditing gap the PR misses), and passed all regression tests.

Root Cause

iOS strips kern attributes from UITextField.AttributedText whenever a plain string is assigned to UITextField.Text. The regression was introduced by PR #20205, which moved CharacterSpacing application to AttributedPlaceholder (for title text). When the user selects an item, platformPicker.Text = selectedItem causes iOS to internally replace AttributedText with a kern-free NSAttributedString, discarding the kern from the placeholder entirely.

Fix Quality

PR's fix: Correct approach but uses read-modify-write (Text = x; UpdateCharacterSpacing()) which depends on AttributedText being reliably readable after Text = assignment — this is fragile. Also misses the OnEditing handler gap, and has a MacCatalyst test crash.

try-fix-1 (WINNER): Uses SetTextWithCharacterSpacing helper that atomically constructs NSAttributedString with KerningAdjustment and directly assigns to AttributedText — bypassing the fragile read-back. Covers all 3 paths. ✅ Passed all tests.

try-fix-2: Also passes but adds state (CharacterSpacing) to MauiPicker — more complex than necessary.

try-fix-3: ❌ Failed — mapper-ordering strategy doesn't cover the Done-button path.

try-fix-4: Passes with same approach as try-fix-1, confirms the atomic NSAttributedString approach is correct.

Selected Fix: try-fix-1 — atomically constructs NSAttributedString with kern, covers all paths, passes all tests. An alternative pr-plus-reviewer (PR fix + #if !MACCATALYST guard) is acceptable if the team prefers a minimal patch, but try-fix-1 is more robust.


Copy link
Copy Markdown
Collaborator

@MauiBot MauiBot left a comment

Choose a reason for hiding this comment

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

🤖 Automated review — alternative fix proposed

The expert-reviewer evaluation compared the PR fix against #1 automatically generated candidates and selected try-fix-1 as the strongest fix.

Why: try-fix-1 passed all 4 regression tests empirically using a SetTextWithCharacterSpacing helper that atomically constructs NSAttributedString with KerningAdjustment instead of the PR's fragile read-modify-write pattern. It also covers the OnEditing handler gap the PR missed and avoids the MacCatalyst test crash entirely.

Please consider applying the candidate diff below (or use it as guidance). Once you push an update, this workflow will re-trigger and re-evaluate.

Candidate diff (`try-fix-1`)
diff --git a/src/Core/src/Handlers/Picker/PickerHandler.iOS.cs b/src/Core/src/Handlers/Picker/PickerHandler.iOS.cs
index a54299d290..11fe557578 100644
--- a/src/Core/src/Handlers/Picker/PickerHandler.iOS.cs
+++ b/src/Core/src/Handlers/Picker/PickerHandler.iOS.cs
@@ -255,7 +255,7 @@ namespace Microsoft.Maui.Handlers
 			if (VirtualView == null || PlatformView == null || pickerSource == null)
 				return;
 
-			PlatformView.Text = VirtualView.GetItem(pickerSource.SelectedIndex);
+			PlatformView.SetTextWithCharacterSpacing(VirtualView.GetItem(pickerSource.SelectedIndex), VirtualView.CharacterSpacing);
 			VirtualView.SelectedIndex = pickerSource.SelectedIndex;
 		}
 
@@ -423,7 +423,7 @@ namespace Microsoft.Maui.Handlers
 				// Reset the TextField's Text so it appears as if typing with a keyboard does not work.
 				var selectedIndex = virtualView.SelectedIndex;
 
-				platformView.Text = virtualView.GetItem(selectedIndex);
+				platformView.SetTextWithCharacterSpacing(virtualView.GetItem(selectedIndex), virtualView.CharacterSpacing);
 
 				// Also clears the undo stack (undo/redo possible on iPads)
 				platformView.UndoManager?.RemoveAllActions();
diff --git a/src/Core/src/Platform/iOS/PickerExtensions.cs b/src/Core/src/Platform/iOS/PickerExtensions.cs
index c2de04d1fd..13e429ae28 100644
--- a/src/Core/src/Platform/iOS/PickerExtensions.cs
+++ b/src/Core/src/Platform/iOS/PickerExtensions.cs
@@ -1,6 +1,7 @@
 #nullable enable
 using System;
 using Foundation;
+using UIKit;
 
 namespace Microsoft.Maui.Platform
 {
@@ -36,18 +37,45 @@ namespace Microsoft.Maui.Platform
 			platformPicker.UpdateAttributedPlaceholder(new NSAttributedString(picker.Title ?? string.Empty, null, picker?.TitleColor?.ToPlatform()));
 		}
 
+		/// <summary>
+		/// Sets text on a picker using AttributedText with kern to avoid iOS clearing
+		/// character spacing when plain Text is assigned.
+		/// </summary>
+		/// <remarks>
+		/// Unlike UpdateCharacterSpacing (which reads back AttributedText and adds kern),
+		/// this creates a fresh NSAttributedString to work around an iOS issue where
+		/// reading AttributedText immediately after setting Text doesn't reliably
+		/// preserve kern in all handler lifecycle contexts.
+		/// </remarks>
+		internal static void SetTextWithCharacterSpacing(this MauiPicker platformPicker, string text, double characterSpacing)
+		{
+			if (characterSpacing == 0)
+			{
+				platformPicker.Text = text;
+				return;
+			}
+
+			var attributes = new UIKit.UIStringAttributes
+			{
+				KerningAdjustment = (float)characterSpacing
+			};
+			platformPicker.AttributedText = new NSAttributedString(text ?? string.Empty, attributes);
+		}
+
 		internal static void UpdatePicker(this MauiPicker platformPicker, IPicker picker, int? newSelectedIndex = null)
 		{
 			var selectedIndex = newSelectedIndex ?? picker.SelectedIndex;
 
 			if (selectedIndex != -1)
 			{
-				platformPicker.Text = picker.GetItem(selectedIndex);
+				platformPicker.SetTextWithCharacterSpacing(picker.GetItem(selectedIndex), picker.CharacterSpacing);
 			}
 			else
 			{
 				platformPicker.Text = null;
 				platformPicker.UpdatePickerTitle(picker);
+				// Applies character spacing to the placeholder when no item is selected
+				platformPicker.UpdateCharacterSpacing(picker);
 			}
 
 			var pickerView = platformPicker.UIPickerView;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-controls-picker Picker community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration platform/ios s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-fix-win AI found a better alternative fix than the PR s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[iOS] Picker loses CharacterSpacing after item selection when Title is set

6 participants