[iOS & Catalyst ] Fixed IsEnabled property should work on Tabs #33369
[iOS & Catalyst ] Fixed IsEnabled property should work on Tabs #33369PureWeen merged 2 commits intodotnet:inflight/currentfrom
Conversation
|
Hey there @@SubhikshaSf4851! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed. |
There was a problem hiding this comment.
Pull request overview
This PR fixes the IsEnabled property on Shell tabs for iOS and MacCatalyst platforms. Previously, disabled tabs at load-time could still be selected and navigated to on these platforms. The fix ensures that the initial IsEnabled state is properly applied to UITabBar items during tab creation and when the items collection changes.
Key Changes
- Added logic to apply initial
IsEnabledstate to UITabBar items during tab setup - Implemented test case demonstrating tab disabled behavior and runtime enable functionality
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellItemRenderer.cs |
Added code to set IsEnabled state on UITabBar items in two places: OnItemsCollectionChanged and CreateTabRenderers |
src/Controls/tests/TestCases.HostApp/Issues/Issue33158.cs |
Created HostApp test page with three tabs (first enabled, second initially disabled, third enabled) to demonstrate the issue and fix |
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33158.cs |
Created NUnit UI test that verifies disabled tab cannot be navigated to, and can be navigated to after being enabled programmatically |
src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellItemRenderer.cs
Outdated
Show resolved
Hide resolved
src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellItemRenderer.cs
Outdated
Show resolved
Hide resolved
PureWeen
left a comment
There was a problem hiding this comment.
PR Review: #33369 - [iOS & Catalyst] Fixed IsEnabled property should work on Tabs
Date: 2026-01-05 | Issue: #33158 | PR: #33369
✅ Final Recommendation: APPROVE
| Phase | Status |
|---|---|
| Pre-Flight | ✅ COMPLETE |
| 🧪 Tests | ✅ COMPLETE |
| 🚦 Gate | ✅ PASSED |
| 🔍 Analysis | ✅ COMPLETE |
| ⚖️ Compare | ✅ COMPLETE |
| 🔬 Regression | ✅ COMPLETE |
| 📋 Report | ✅ COMPLETE |
📋 Issue Summary
Issue #33158: TabBarBackgroundColor, TabBarUnselectedColor, and IsEnabled Not Working as Expected in Shell
The IsEnabled property on Shell TabBar tabs does not work on iOS/MacCatalyst. Setting IsEnabled="False" on a Tab does not disable the tab - it remains selectable and navigable.
Steps to Reproduce:
- Create a Shell page with a TabBar
- Add multiple Tab items with icons
- Set
IsEnabled="False"on one of the tabs - Run the application
- Observe: The disabled tab is still selectable
Expected Behavior:
- Tabs with
IsEnabled="False"should be disabled and not selectable
Platforms Affected:
- iOS
- Android
- Windows
- MacCatalyst
Note: PR mentions iOS 26/Catalyst 26 has separate handling in follow-up PR #33337
📁 Files Changed
| File | Type | Changes |
|---|---|---|
src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellItemRenderer.cs |
Fix | +28 lines |
src/Controls/tests/TestCases.HostApp/Issues/Issue33158.cs |
Test | +130 lines |
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33158.cs |
Test | +30 lines |
Test Type: UI Tests
💬 PR Discussion Summary
Key Comments:
- Copilot reviewer provided overview of changes
- PR author notes iOS 26/Catalyst 26 handled separately in PR #33337
Reviewer Feedback (Copilot):
- Code duplication between
OnItemsCollectionChangedandCreateTabRenderers- suggests extracting to separate method - Edge case concern:
TabBar.Items.Length >= items.Countmay not handle edge cases properly - suggests usingMath.Min()
Disagreements to Investigate:
| File:Line | Reviewer Says | Author Says | Status |
|---|---|---|---|
| ShellItemRenderer.cs:256 | Extract duplicated code to separate method | (No response) | |
| ShellItemRenderer.cs:255 | Use Math.Min() for safer iteration |
(No response) |
Author Uncertainty:
- None explicitly stated
🧪 Tests
Status: ✅ COMPLETE
- PR includes UI tests
- Tests reproduce the issue (taps disabled tab, verifies no navigation, then enables and verifies navigation works)
- Tests follow naming convention (
Issue33158)
Test Files:
- HostApp:
src/Controls/tests/TestCases.HostApp/Issues/Issue33158.cs - NUnit:
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33158.cs
Test Structure:
- Shell with 3 tabs: FirstPage (enabled), SecondTab (disabled), ThirdTab (enabled)
- Test navigates to ThirdTab, tries to tap disabled SecondTab (expects no navigation)
- Button on ThirdPage enables SecondTab at runtime
- Test then taps SecondTab and expects successful navigation
#if TEST_FAILS_ON_WINDOWS - excludes Windows (separate PR #26728)
🚦 Gate - Test Verification
Status: ✅ PASSED
- Tests PASS with fix
- Fix files reverted to main
- Tests FAIL without fix
- Fix files restored
Result: PASSED ✅
Verification Details:
- Platform: iOS (simulator AC8BCB28-A72D-4A2D-90E7-E78FF0BA07EE, iOS 18.5)
- Tests WITHOUT fix: FAIL ✅ (expected - issue detected)
- Tests WITH fix: PASS ✅ (expected - fix works)
🔍 Analysis
Status: ✅ COMPLETE
- Reviewed pre-flight findings
- Researched git history for root cause
- Formed independent opinion on fix approach
Root Cause:
The iOS ShellItemRenderer was missing the initial application of IsEnabled state to UITabBarItems. The code correctly handles runtime changes via OnShellSectionPropertyChanged (line 267-276), which sets TabBar.Items[index].Enabled = shellSection.IsEnabled when the property changes. However, when tabs are initially created in CreateTabRenderers() or added via OnItemsCollectionChanged(), the IsEnabled state was never applied to the UITabBarItem.Enabled property.
How Android Does It (for comparison):
Android handles this through BottomNavigationViewUtils.SetupMenu() which takes a tuple (title, icon, tabEnabled) and calls UpdateEnabled(item.tabEnabled, menuItem) during setup. The enabled state is passed as part of the data model and applied during menu creation - it's baked into the setup flow.
Alternative Approaches Considered:
| Alternative | Location | Evaluation |
|---|---|---|
| 1. Apply IsEnabled when creating UITabBarItem | Inside the loop where ViewControllers are created | ❌ TabBar.Items is not yet populated until after ViewControllers is set |
| 2. Use a KVO observer on TabBar.Items | Observe when TabBar.Items changes | ❌ Overcomplicated, adds complexity |
| 3. Override ViewDidAppear to apply IsEnabled | In ShellItemRenderer.ViewDidAppear | ❌ Would run every time view appears, wasteful |
| 4. Separate helper method called after ViewControllers assignment | Current PR approach | ✅ Clean, explicit, called at right time |
Why the PR's approach is correct:
The key insight is that TabBar.Items is populated by iOS after ViewControllers is assigned. You cannot set TabBar.Items[i].Enabled inside the loop that builds viewControllers because TabBar.Items doesn't exist yet. The PR correctly:
- Assigns ViewControllers (which triggers iOS to create TabBar.Items)
- Immediately after, calls
SetTabItemsEnabledState()to apply the IsEnabled state
My Approach: The PR's approach is correct. The only improvements I would suggest:
- Use
Math.Min()as Copilot suggested for safer iteration (though edge case is unlikely) - The code duplication is acceptable since the method is small and self-contained
⚖️ Compare
Status: ✅ COMPLETE
| Approach | Test Result | Lines Changed | Complexity | Recommendation |
|---|---|---|---|---|
| PR's fix | ✅ PASS | +28 | Low | ✅ Accept with minor suggestion |
| My approach | N/A | Same | Same | PR's approach is correct |
Detailed Comparison
PR's Implementation:
void SetTabItemsEnabledState()
{
if (TabBar?.Items is null) return;
var items = ShellItemController.GetItems();
if (items is null) return;
if (TabBar.Items.Length >= items.Count)
{
for (int tabIndex = 0; tabIndex < items.Count; tabIndex++)
{
TabBar.Items[tabIndex].Enabled = items[tabIndex].IsEnabled;
}
}
}Assessment:
| Criteria | PR's Fix | Notes |
|---|---|---|
| Correctness | ✅ Correct | Applies IsEnabled after ViewControllers assigned |
| Null safety | ✅ Good | Checks TabBar?.Items and items for null |
| Timing | ✅ Correct | Called immediately after ViewControllers = viewControllers |
| Edge case handling | See below |
Copilot Suggestion Analysis
Suggestion 1: Code Duplication
"Extract duplicated code to separate method"
My Finding: ✅ PR author already did this. The method SetTabItemsEnabledState() is extracted and called from both CreateTabRenderers() (line 344) and OnItemsCollectionChanged() (line 250). The code is NOT duplicated - it's properly extracted into a helper method.
Suggestion 2: Use Math.Min() for safer iteration
"Use Math.Min(TabBar.Items.Length, items.Count) to prevent potential index out of bounds"
My Finding:
if (TabBar.Items.Length >= items.Count)This means if TabBar.Items.Length < items.Count, the loop doesn't run at all. This is safe but silently fails.
Analysis of the edge case:
TabBar.Itemsis populated by iOS whenViewControllersis set- The count should always match because iOS creates one UITabBarItem per ViewController
- If they don't match, something is seriously wrong with the UITabBarController state
- The current approach (skip if mismatched) is defensive but may hide bugs
Verdict: The current approach is acceptable. Using Math.Min() would apply enabled state to as many tabs as possible, which might be marginally better, but the scenario where counts mismatch indicates a larger problem that should be investigated rather than worked around.
Recommendation
Accept PR as-is. The implementation is:
- ✅ Architecturally correct (applies state after iOS creates UITabBarItems)
- ✅ Not duplicated (properly extracted to helper method)
- ✅ Null-safe
- ✅ Tests pass and correctly catch the bug
⚠️ Minor: Could useMath.Min()but current approach is also valid
🔬 Regression
Status: ✅ COMPLETE
Edge Cases Verified:
| Edge Case | Status | Finding |
|---|---|---|
| More Tab (>5 tabs) | ✅ Safe | UpdateMoreCellsEnabled() is called via GoTo() → SelectedViewController setter. Tabs 5+ in "More" menu handled separately. |
| Runtime IsEnabled change | ✅ Already works | OnShellSectionPropertyChanged handles this at line 267-275 |
| Tab collection changes | ✅ Covered | SetTabItemsEnabledState() is called in OnItemsCollectionChanged() |
| Initial load | ✅ Fixed | SetTabItemsEnabledState() is called in CreateTabRenderers() |
| Windows platform | Excluded via #if TEST_FAILS_ON_WINDOWS - PR #26728 tracks this |
|
| MacCatalyst | ✅ Same handler | Uses same ShellItemRenderer.cs as iOS |
Disagreements Investigated:
| Topic | Finding |
|---|---|
| Copilot: "Extract duplicated code" | ✅ Already done - SetTabItemsEnabledState() is a helper method |
| Copilot: "Use Math.Min()" |
Potential Regressions: None identified. The fix is additive and doesn't change existing behavior.
Final Recommendation: ✅ APPROVE
Justification:
- Tests validate the fix - Gate verification confirmed tests FAIL without fix and PASS with fix on iOS 18.5
- Architecturally correct - Applies IsEnabled state after iOS creates UITabBarItems (the only correct time)
- Not hacky - Follows same pattern as Android (
BottomNavigationViewUtils.SetupMenu), properly extracted to helper method - No regressions identified - All code paths covered (initial load, collection change, runtime change, "More" tab)
- Copilot suggestions addressed - Code duplication concern invalid (method IS extracted), Math.Min() optional but current approach safe
- Minimal and focused - Only 28 lines added, all directly related to the bug fix
<!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Root Cause The load-time handling of the `IsEnabled` property for tab items was not implemented on iOS. As a result, disabled tabs could still be selectable and navigateable ### Description of Change Updated `ShellItemRenderer.cs` to set the `IsEnabled` property of each `TabBar` item based on the corresponding `IsEnabled` value during both initial creation and when the items collection changes. <!-- Enter description of the fix in this section --> ### 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 #33158 ### Follow-up PR : - On **iOS 26** and **Catalyst 26**, navigation between tabs via drag and selection gestures is handled separately in this PR #33337. ### Tested the behavior in the following platforms - [ ] Windows - [x] Android - [x] iOS - [x] Mac | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/d133ccd3-abb1-44dd-9135-16b1ebeeb8e6"> | <video src="https://github.com/user-attachments/assets/223f454c-fc1a-4167-b265-8ef6c7e0c8c6"> | <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. -->
<!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Root Cause The load-time handling of the `IsEnabled` property for tab items was not implemented on iOS. As a result, disabled tabs could still be selectable and navigateable ### Description of Change Updated `ShellItemRenderer.cs` to set the `IsEnabled` property of each `TabBar` item based on the corresponding `IsEnabled` value during both initial creation and when the items collection changes. <!-- Enter description of the fix in this section --> ### 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 #33158 ### Follow-up PR : - On **iOS 26** and **Catalyst 26**, navigation between tabs via drag and selection gestures is handled separately in this PR #33337. ### Tested the behavior in the following platforms - [ ] Windows - [x] Android - [x] iOS - [x] Mac | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/d133ccd3-abb1-44dd-9135-16b1ebeeb8e6"> | <video src="https://github.com/user-attachments/assets/223f454c-fc1a-4167-b265-8ef6c7e0c8c6"> | <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. -->
<!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Root Cause The load-time handling of the `IsEnabled` property for tab items was not implemented on iOS. As a result, disabled tabs could still be selectable and navigateable ### Description of Change Updated `ShellItemRenderer.cs` to set the `IsEnabled` property of each `TabBar` item based on the corresponding `IsEnabled` value during both initial creation and when the items collection changes. <!-- Enter description of the fix in this section --> ### 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 #33158 ### Follow-up PR : - On **iOS 26** and **Catalyst 26**, navigation between tabs via drag and selection gestures is handled separately in this PR #33337. ### Tested the behavior in the following platforms - [ ] Windows - [x] Android - [x] iOS - [x] Mac | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/d133ccd3-abb1-44dd-9135-16b1ebeeb8e6"> | <video src="https://github.com/user-attachments/assets/223f454c-fc1a-4167-b265-8ef6c7e0c8c6"> | <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. -->
<!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Root Cause The load-time handling of the `IsEnabled` property for tab items was not implemented on iOS. As a result, disabled tabs could still be selectable and navigateable ### Description of Change Updated `ShellItemRenderer.cs` to set the `IsEnabled` property of each `TabBar` item based on the corresponding `IsEnabled` value during both initial creation and when the items collection changes. <!-- Enter description of the fix in this section --> ### 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 #33158 ### Follow-up PR : - On **iOS 26** and **Catalyst 26**, navigation between tabs via drag and selection gestures is handled separately in this PR #33337. ### Tested the behavior in the following platforms - [ ] Windows - [x] Android - [x] iOS - [x] Mac | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/d133ccd3-abb1-44dd-9135-16b1ebeeb8e6"> | <video src="https://github.com/user-attachments/assets/223f454c-fc1a-4167-b265-8ef6c7e0c8c6"> | <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. -->
<!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Root Cause The load-time handling of the `IsEnabled` property for tab items was not implemented on iOS. As a result, disabled tabs could still be selectable and navigateable ### Description of Change Updated `ShellItemRenderer.cs` to set the `IsEnabled` property of each `TabBar` item based on the corresponding `IsEnabled` value during both initial creation and when the items collection changes. <!-- Enter description of the fix in this section --> ### 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 #33158 ### Follow-up PR : - On **iOS 26** and **Catalyst 26**, navigation between tabs via drag and selection gestures is handled separately in this PR #33337. ### Tested the behavior in the following platforms - [ ] Windows - [x] Android - [x] iOS - [x] Mac | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/d133ccd3-abb1-44dd-9135-16b1ebeeb8e6"> | <video src="https://github.com/user-attachments/assets/223f454c-fc1a-4167-b265-8ef6c7e0c8c6"> | <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. -->
<!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Root Cause The load-time handling of the `IsEnabled` property for tab items was not implemented on iOS. As a result, disabled tabs could still be selectable and navigateable ### Description of Change Updated `ShellItemRenderer.cs` to set the `IsEnabled` property of each `TabBar` item based on the corresponding `IsEnabled` value during both initial creation and when the items collection changes. <!-- Enter description of the fix in this section --> ### 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 #33158 ### Follow-up PR : - On **iOS 26** and **Catalyst 26**, navigation between tabs via drag and selection gestures is handled separately in this PR #33337. ### Tested the behavior in the following platforms - [ ] Windows - [x] Android - [x] iOS - [x] Mac | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/d133ccd3-abb1-44dd-9135-16b1ebeeb8e6"> | <video src="https://github.com/user-attachments/assets/223f454c-fc1a-4167-b265-8ef6c7e0c8c6"> | <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. -->
<!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Root Cause The load-time handling of the `IsEnabled` property for tab items was not implemented on iOS. As a result, disabled tabs could still be selectable and navigateable ### Description of Change Updated `ShellItemRenderer.cs` to set the `IsEnabled` property of each `TabBar` item based on the corresponding `IsEnabled` value during both initial creation and when the items collection changes. <!-- Enter description of the fix in this section --> ### 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 #33158 ### Follow-up PR : - On **iOS 26** and **Catalyst 26**, navigation between tabs via drag and selection gestures is handled separately in this PR #33337. ### Tested the behavior in the following platforms - [ ] Windows - [x] Android - [x] iOS - [x] Mac | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/d133ccd3-abb1-44dd-9135-16b1ebeeb8e6"> | <video src="https://github.com/user-attachments/assets/223f454c-fc1a-4167-b265-8ef6c7e0c8c6"> | <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. -->
## What's Coming .NET MAUI inflight/candidate introduces significant improvements across all platforms with focus on quality, performance, and developer experience. This release includes 16 commits with various improvements, bug fixes, and enhancements. ## Checkbox - [Android] Implement material3 support for CheckBox by @HarishwaranVijayakumar in #33339 <details> <summary>🔧 Fixes</summary> - [Implement Material3 Support for CheckBox](#33338) </details> ## CollectionView - [Android] Fixed EmptyView doesn’t display when CollectionView is placed inside a VerticalStackLayout by @NanthiniMahalingam in #33134 <details> <summary>🔧 Fixes</summary> - [CollectionView does not show an EmptyView template with an empty collection](#32932) </details> ## Essentials - [Windows]Fix NullReferenceException in OpenReadAsync for FileResult created with full path by @devanathan-vaithiyanathan in #28238 <details> <summary>🔧 Fixes</summary> - [[Windows] FileResult(string fullPath) not initialized properly](#26858) </details> ## Image - Fix Glide IllegalArgumentException in MauiCustomTarget.clear() for destroyed activities by @jfversluis via @Copilot in #29780 <details> <summary>🔧 Fixes</summary> - [java.lang.IllegalArgumentException: You cannot start a load for a destroyed activity - glide](#29699) </details> ## Label - [Android] Fix for Label WordWrap width issue causing HorizontalOptions misalignment by @praveenkumarkarunanithi in #33281 <details> <summary>🔧 Fixes</summary> - [[Android] Unexpected Line Breaks in Android, Label with WordWrap Mode Due to Trailing Space.](#31782) - [Label not sized correctly on Android](#27614) </details> - Fix to Improve Flyout Accessibility by Adjusting UITableViewController Labels by @SuthiYuvaraj in #31619 <details> <summary>🔧 Fixes</summary> - [Navigation section present under hamburger are programmatically define as table :A11y_.NET maui_User can get all the insights of Dashboard_Devtools](#30894) </details> ## Mediapicker - [Regression][iOS] Fix MediaPicker PickPhotosAsync getting file name in contentType property by @devanathan-vaithiyanathan in #33390 <details> <summary>🔧 Fixes</summary> - [[iOS] MediaPicker PickPhotosAsync getting file name in contentType property](#33348) </details> ## Navigation - Fix handler not disconnected when removing non visible pages using RemovePage() by @Vignesh-SF3580 in #32289 <details> <summary>🔧 Fixes</summary> - [NavigationPage.Navigation.RemovePage() fails to disconnect handlers when removing pages, unlike ContentPage.Navigation.RemovePage()](#32239) </details> ## Picker - [Android] Fix Picker IsOpen not reset when picker is dismissed by @devanathan-vaithiyanathan in #33332 <details> <summary>🔧 Fixes</summary> - [[Android] Picker IsOpen not reset when picker is dismissed](#33331) </details> ## Shell - [iOS & Catalyst ] Fixed IsEnabled property should work on Tabs by @SubhikshaSf4851 in #33369 <details> <summary>🔧 Fixes</summary> - [[Catalyst] TabBarBackgroundColor, TabBarUnselectedColor, and IsEnabled Not Working as Expected in Shell](#33158) </details> - [iOS,Windows] Fix navigation bar colors not resetting when switching ShellContent by @Vignesh-SF3580 in #33228 <details> <summary>🔧 Fixes</summary> - [[iOS, Windows] Shell Navigation bar colors are not updated correctly when switching ShellContent](#33227) </details> - [iOS] Fixed Shell navigation on search handler suggestion selection by @SubhikshaSf4851 in #33406 <details> <summary>🔧 Fixes</summary> - [[iOS] Clicking on search suggestions fails to navigate to detail page correctly](#33356) </details> ## Templates - Fix VoiceOver doesnot announces the State of the ComboBox by @SuthiYuvaraj in #32286 ## Xaml - [XSG][BindingSourceGen] Add support for CommunityToolkit.Mvvm ObservablePropertyAttribute by @simonrozsival via @Copilot in #33028 <details> <summary>🔧 Fixes</summary> - [[XSG] Add heuristic to support bindable properties generated by other source generators](#32597) </details> <details> <summary>📦 Other (2)</summary> - [XSG] Improve diagnostic reporting during binding compilation by @simonrozsival via @Copilot in #32905 - [Testing] Fixed Test case failure in PR 33574 - [01/19/2026] Candidate - 1 by @TamilarasanSF4853 in #33602 </details> **Full Changelog**: main...inflight/candidate
#33337) <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Root Cause On iOS and Mac Catalyst 26 version, drag and selection gestures allow navigation to disabled tabs which leads to inconsistent with the UI and expected behavior. ### Description of Change * Since navigation can be achieved via drag and select in iOS and Mac Catalyst version 26, updated the `ShouldSelectViewController` logic in `ShellItemRenderer.cs` to prevent selection of disabled tabs on iOS and Mac Catalyst by returning `false` when a tab's `IsEnabled` property is `false`. <!-- Enter description of the fix in this section --> ### 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 #33158 ### Tested the behavior in the following platforms - [ ] Windows - [x] Android - [x] iOS - [x] Mac Follow UP PR : [33369](#33369) | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/837f9197-4f92-4797-8b4a-5f40cc0f2af2"> | <video src="https://github.com/user-attachments/assets/89449bc0-bd23-4f10-8bbd-102cce85f64e"> | <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. -->
dotnet#33337) <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Root Cause On iOS and Mac Catalyst 26 version, drag and selection gestures allow navigation to disabled tabs which leads to inconsistent with the UI and expected behavior. ### Description of Change * Since navigation can be achieved via drag and select in iOS and Mac Catalyst version 26, updated the `ShouldSelectViewController` logic in `ShellItemRenderer.cs` to prevent selection of disabled tabs on iOS and Mac Catalyst by returning `false` when a tab's `IsEnabled` property is `false`. <!-- Enter description of the fix in this section --> ### 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 dotnet#33158 ### Tested the behavior in the following platforms - [ ] Windows - [x] Android - [x] iOS - [x] Mac Follow UP PR : [33369](dotnet#33369) | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/837f9197-4f92-4797-8b4a-5f40cc0f2af2"> | <video src="https://github.com/user-attachments/assets/89449bc0-bd23-4f10-8bbd-102cce85f64e"> | <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. -->
Root Cause
The load-time handling of the
IsEnabledproperty for tab items was not implemented on iOS. As a result, disabled tabs could still be selectable and navigateableDescription of Change
Updated
ShellItemRenderer.csto set theIsEnabledproperty of eachTabBaritem based on the correspondingIsEnabledvalue during both initial creation and when the items collection changes.Issues Fixed
Fixes #33158
Follow-up PR :
Tested the behavior in the following platforms
BeforeFix33158.mov
AfterFix33158.mov