Fixed the NRE in CarouselViewController on iOS 15.5 & 16.4 #30838
Fixed the NRE in CarouselViewController on iOS 15.5 & 16.4 #30838rmarinho merged 5 commits intodotnet:inflight/currentfrom
Conversation
|
Hey there @@Ahamed-Ali! 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 a null reference exception in CarouselViewController that occurs on iOS 15.5 and 16.4 when updating CarouselView's ItemsSource from another page. The issue stems from iOS version differences in when GetCell is called during navigation scenarios.
- Adds a null check and initialization for _carouselViewLoopManager before use
- Provides fallback handling when the loop manager cannot be initialized
- Includes comprehensive UI tests to verify the fix across different iOS versions
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/Controls/src/Core/Handlers/Items/iOS/CarouselViewController.cs | Adds null check and initialization logic for _carouselViewLoopManager to prevent NRE |
| src/Controls/tests/TestCases.HostApp/Issues/Issue28557.cs | Creates UI test page with CarouselView and navigation scenario to reproduce the issue |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28557.cs | Implements automated test case to verify the fix works correctly |
| if (_carouselViewLoopManager is null) | ||
| { | ||
| UpdateDefaultCell(defaultCell, correctedIndexPath); | ||
| InitializeCarouselViewLoopManager(); |
There was a problem hiding this comment.
The InitializeCarouselViewLoopManager() method is called but not defined in this class. This will cause a compilation error unless the method exists elsewhere in the class hierarchy.
There was a problem hiding this comment.
The InitializeCarouselViewLoopManager() method is properly implemented in the CarouselViewController class, so calling it will not cause any compilation errors.
|
/azp run MAUI-UITests-public |
|
Azure Pipelines successfully started running 1 pipeline(s). |
| if (_carouselViewLoopManager is null) | ||
| { | ||
| UpdateDefaultCell(defaultCell, correctedIndexPath); | ||
| InitializeCarouselViewLoopManager(); |
There was a problem hiding this comment.
Called on every GetCell when Loop == true and manager is null, have an impact in the performance?
There was a problem hiding this comment.
This initialization typically occurs in either ViewDidLoad() or the Setup() method, which is called during AttachingToWindow().
The edge case that this fix addresses is specific to iOS 15/16, where navigation between pages involving CarouselView updates can cause the initialization to happen only once—just when it's needed.
After the initial setup, subsequent calls to GetCell() will bypass the null check, resulting in virtually no performance impact. @jsuarezruiz
| { | ||
| UpdateTemplatedCell(templatedCell, correctedIndexPath); | ||
| // Fallback to base implementation if manager couldn't be initialized | ||
| cell = base.GetCell(collectionView, indexPath); |
There was a problem hiding this comment.
The fallback completely bypasses loop behavior, could we include a comment indicating it here?
There was a problem hiding this comment.
I have added the comment
| if (cell is DefaultCell defaultCell) | ||
| if (ItemsView?.Loop == true) | ||
| { | ||
| // In iOS 15 and 16, when the ItemsSource of the CarouselView is updated from another page |
|
/rebase |
14a0bf0 to
4868c3c
Compare
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
<!-- 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! ### Root Cause of the issue - Upon analysis, in iOS versions 18.4 and 18.0, GetCell is called when PopAsync is invoked—navigating back to the MainPage (which contains the CarouselView). At this point, _carouselViewLoopManager is properly set through the Setup method, and a valid IndexPath is passed into GetCell, resulting in correct updates. - However, in iOS versions 15.5 and 16.0, GetCell is triggered immediately when _viewModel.Source[0] is updated. At that time, the CarouselViewLoopManager is still null, and since a valid index cannot be retrieved, the else part of GetCell is executed with an invalid IndexPath, leading to an ArgumentNullException. ### Description of Change - To prevent ArgumentNullException caused by invalid IndexPath values during the loop initialization phase, ensure that the CarouselViewLoopManager is fully initialized before it is used. Once initialized, it correctly returns a valid IndexPath using FromRowSection, allowing the templated cell to be updated as expected in all iOS versions. ### Issues Fixed Fixes #28557 ### Tested the behaviour in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Tested Version | iOS Version | App Crashed | |----------|----------| | 15.5 | Yes | | 16.0 | Yes | | 17.4 | No | | 18.4 | No | ### Screenshot ### iOS 15.5 | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/4df6973e-c658-4c89-a085-cc2035a593bf"> | <video src="https://github.com/user-attachments/assets/25840d66-fa41-4a00-8e53-a262b405eca3"> | ### iOS 16.0 | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/882829ed-fef4-40e9-a450-2972b4134c8e"> | <video src="https://github.com/user-attachments/assets/4a5d0c48-e340-4b51-939e-6a6bf7518db7"> | ### iOS 17.4 && iOS 18.4 | iOS 17.4 | iOS 18.4 | |----------|----------| | <video src="https://github.com/user-attachments/assets/5c167003-f5af-4989-87c7-d09b8d3b7b81"> | <video src="https://github.com/user-attachments/assets/9c44bc1d-0956-4795-994b-2c4c314d40a7"> |
<!-- 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! ### Root Cause of the issue - Upon analysis, in iOS versions 18.4 and 18.0, GetCell is called when PopAsync is invoked—navigating back to the MainPage (which contains the CarouselView). At this point, _carouselViewLoopManager is properly set through the Setup method, and a valid IndexPath is passed into GetCell, resulting in correct updates. - However, in iOS versions 15.5 and 16.0, GetCell is triggered immediately when _viewModel.Source[0] is updated. At that time, the CarouselViewLoopManager is still null, and since a valid index cannot be retrieved, the else part of GetCell is executed with an invalid IndexPath, leading to an ArgumentNullException. ### Description of Change - To prevent ArgumentNullException caused by invalid IndexPath values during the loop initialization phase, ensure that the CarouselViewLoopManager is fully initialized before it is used. Once initialized, it correctly returns a valid IndexPath using FromRowSection, allowing the templated cell to be updated as expected in all iOS versions. ### Issues Fixed Fixes #28557 ### Tested the behaviour in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Tested Version | iOS Version | App Crashed | |----------|----------| | 15.5 | Yes | | 16.0 | Yes | | 17.4 | No | | 18.4 | No | ### Screenshot ### iOS 15.5 | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/4df6973e-c658-4c89-a085-cc2035a593bf"> | <video src="https://github.com/user-attachments/assets/25840d66-fa41-4a00-8e53-a262b405eca3"> | ### iOS 16.0 | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/882829ed-fef4-40e9-a450-2972b4134c8e"> | <video src="https://github.com/user-attachments/assets/4a5d0c48-e340-4b51-939e-6a6bf7518db7"> | ### iOS 17.4 && iOS 18.4 | iOS 17.4 | iOS 18.4 | |----------|----------| | <video src="https://github.com/user-attachments/assets/5c167003-f5af-4989-87c7-d09b8d3b7b81"> | <video src="https://github.com/user-attachments/assets/9c44bc1d-0956-4795-994b-2c4c314d40a7"> |
<!-- 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! ### Root Cause of the issue - Upon analysis, in iOS versions 18.4 and 18.0, GetCell is called when PopAsync is invoked—navigating back to the MainPage (which contains the CarouselView). At this point, _carouselViewLoopManager is properly set through the Setup method, and a valid IndexPath is passed into GetCell, resulting in correct updates. - However, in iOS versions 15.5 and 16.0, GetCell is triggered immediately when _viewModel.Source[0] is updated. At that time, the CarouselViewLoopManager is still null, and since a valid index cannot be retrieved, the else part of GetCell is executed with an invalid IndexPath, leading to an ArgumentNullException. ### Description of Change - To prevent ArgumentNullException caused by invalid IndexPath values during the loop initialization phase, ensure that the CarouselViewLoopManager is fully initialized before it is used. Once initialized, it correctly returns a valid IndexPath using FromRowSection, allowing the templated cell to be updated as expected in all iOS versions. ### Issues Fixed Fixes #28557 ### Tested the behaviour in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Tested Version | iOS Version | App Crashed | |----------|----------| | 15.5 | Yes | | 16.0 | Yes | | 17.4 | No | | 18.4 | No | ### Screenshot ### iOS 15.5 | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/4df6973e-c658-4c89-a085-cc2035a593bf"> | <video src="https://github.com/user-attachments/assets/25840d66-fa41-4a00-8e53-a262b405eca3"> | ### iOS 16.0 | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/882829ed-fef4-40e9-a450-2972b4134c8e"> | <video src="https://github.com/user-attachments/assets/4a5d0c48-e340-4b51-939e-6a6bf7518db7"> | ### iOS 17.4 && iOS 18.4 | iOS 17.4 | iOS 18.4 | |----------|----------| | <video src="https://github.com/user-attachments/assets/5c167003-f5af-4989-87c7-d09b8d3b7b81"> | <video src="https://github.com/user-attachments/assets/9c44bc1d-0956-4795-994b-2c4c314d40a7"> |
<!-- 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! ### Root Cause of the issue - Upon analysis, in iOS versions 18.4 and 18.0, GetCell is called when PopAsync is invoked—navigating back to the MainPage (which contains the CarouselView). At this point, _carouselViewLoopManager is properly set through the Setup method, and a valid IndexPath is passed into GetCell, resulting in correct updates. - However, in iOS versions 15.5 and 16.0, GetCell is triggered immediately when _viewModel.Source[0] is updated. At that time, the CarouselViewLoopManager is still null, and since a valid index cannot be retrieved, the else part of GetCell is executed with an invalid IndexPath, leading to an ArgumentNullException. ### Description of Change - To prevent ArgumentNullException caused by invalid IndexPath values during the loop initialization phase, ensure that the CarouselViewLoopManager is fully initialized before it is used. Once initialized, it correctly returns a valid IndexPath using FromRowSection, allowing the templated cell to be updated as expected in all iOS versions. ### Issues Fixed Fixes #28557 ### Tested the behaviour in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Tested Version | iOS Version | App Crashed | |----------|----------| | 15.5 | Yes | | 16.0 | Yes | | 17.4 | No | | 18.4 | No | ### Screenshot ### iOS 15.5 | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/4df6973e-c658-4c89-a085-cc2035a593bf"> | <video src="https://github.com/user-attachments/assets/25840d66-fa41-4a00-8e53-a262b405eca3"> | ### iOS 16.0 | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/882829ed-fef4-40e9-a450-2972b4134c8e"> | <video src="https://github.com/user-attachments/assets/4a5d0c48-e340-4b51-939e-6a6bf7518db7"> | ### iOS 17.4 && iOS 18.4 | iOS 17.4 | iOS 18.4 | |----------|----------| | <video src="https://github.com/user-attachments/assets/5c167003-f5af-4989-87c7-d09b8d3b7b81"> | <video src="https://github.com/user-attachments/assets/9c44bc1d-0956-4795-994b-2c4c314d40a7"> |
<!-- 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! ### Root Cause of the issue - Upon analysis, in iOS versions 18.4 and 18.0, GetCell is called when PopAsync is invoked—navigating back to the MainPage (which contains the CarouselView). At this point, _carouselViewLoopManager is properly set through the Setup method, and a valid IndexPath is passed into GetCell, resulting in correct updates. - However, in iOS versions 15.5 and 16.0, GetCell is triggered immediately when _viewModel.Source[0] is updated. At that time, the CarouselViewLoopManager is still null, and since a valid index cannot be retrieved, the else part of GetCell is executed with an invalid IndexPath, leading to an ArgumentNullException. ### Description of Change - To prevent ArgumentNullException caused by invalid IndexPath values during the loop initialization phase, ensure that the CarouselViewLoopManager is fully initialized before it is used. Once initialized, it correctly returns a valid IndexPath using FromRowSection, allowing the templated cell to be updated as expected in all iOS versions. ### Issues Fixed Fixes #28557 ### Tested the behaviour in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Tested Version | iOS Version | App Crashed | |----------|----------| | 15.5 | Yes | | 16.0 | Yes | | 17.4 | No | | 18.4 | No | ### Screenshot ### iOS 15.5 | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/4df6973e-c658-4c89-a085-cc2035a593bf"> | <video src="https://github.com/user-attachments/assets/25840d66-fa41-4a00-8e53-a262b405eca3"> | ### iOS 16.0 | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/882829ed-fef4-40e9-a450-2972b4134c8e"> | <video src="https://github.com/user-attachments/assets/4a5d0c48-e340-4b51-939e-6a6bf7518db7"> | ### iOS 17.4 && iOS 18.4 | iOS 17.4 | iOS 18.4 | |----------|----------| | <video src="https://github.com/user-attachments/assets/5c167003-f5af-4989-87c7-d09b8d3b7b81"> | <video src="https://github.com/user-attachments/assets/9c44bc1d-0956-4795-994b-2c4c314d40a7"> |
<!-- 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! ### Root Cause of the issue - Upon analysis, in iOS versions 18.4 and 18.0, GetCell is called when PopAsync is invoked—navigating back to the MainPage (which contains the CarouselView). At this point, _carouselViewLoopManager is properly set through the Setup method, and a valid IndexPath is passed into GetCell, resulting in correct updates. - However, in iOS versions 15.5 and 16.0, GetCell is triggered immediately when _viewModel.Source[0] is updated. At that time, the CarouselViewLoopManager is still null, and since a valid index cannot be retrieved, the else part of GetCell is executed with an invalid IndexPath, leading to an ArgumentNullException. ### Description of Change - To prevent ArgumentNullException caused by invalid IndexPath values during the loop initialization phase, ensure that the CarouselViewLoopManager is fully initialized before it is used. Once initialized, it correctly returns a valid IndexPath using FromRowSection, allowing the templated cell to be updated as expected in all iOS versions. ### Issues Fixed Fixes #28557 ### Tested the behaviour in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Tested Version | iOS Version | App Crashed | |----------|----------| | 15.5 | Yes | | 16.0 | Yes | | 17.4 | No | | 18.4 | No | ### Screenshot ### iOS 15.5 | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/4df6973e-c658-4c89-a085-cc2035a593bf"> | <video src="https://github.com/user-attachments/assets/25840d66-fa41-4a00-8e53-a262b405eca3"> | ### iOS 16.0 | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/882829ed-fef4-40e9-a450-2972b4134c8e"> | <video src="https://github.com/user-attachments/assets/4a5d0c48-e340-4b51-939e-6a6bf7518db7"> | ### iOS 17.4 && iOS 18.4 | iOS 17.4 | iOS 18.4 | |----------|----------| | <video src="https://github.com/user-attachments/assets/5c167003-f5af-4989-87c7-d09b8d3b7b81"> | <video src="https://github.com/user-attachments/assets/9c44bc1d-0956-4795-994b-2c4c314d40a7"> |
<!-- 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! ### Root Cause of the issue - Upon analysis, in iOS versions 18.4 and 18.0, GetCell is called when PopAsync is invoked—navigating back to the MainPage (which contains the CarouselView). At this point, _carouselViewLoopManager is properly set through the Setup method, and a valid IndexPath is passed into GetCell, resulting in correct updates. - However, in iOS versions 15.5 and 16.0, GetCell is triggered immediately when _viewModel.Source[0] is updated. At that time, the CarouselViewLoopManager is still null, and since a valid index cannot be retrieved, the else part of GetCell is executed with an invalid IndexPath, leading to an ArgumentNullException. ### Description of Change - To prevent ArgumentNullException caused by invalid IndexPath values during the loop initialization phase, ensure that the CarouselViewLoopManager is fully initialized before it is used. Once initialized, it correctly returns a valid IndexPath using FromRowSection, allowing the templated cell to be updated as expected in all iOS versions. ### Issues Fixed Fixes #28557 ### Tested the behaviour in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Tested Version | iOS Version | App Crashed | |----------|----------| | 15.5 | Yes | | 16.0 | Yes | | 17.4 | No | | 18.4 | No | ### Screenshot ### iOS 15.5 | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/4df6973e-c658-4c89-a085-cc2035a593bf"> | <video src="https://github.com/user-attachments/assets/25840d66-fa41-4a00-8e53-a262b405eca3"> | ### iOS 16.0 | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/882829ed-fef4-40e9-a450-2972b4134c8e"> | <video src="https://github.com/user-attachments/assets/4a5d0c48-e340-4b51-939e-6a6bf7518db7"> | ### iOS 17.4 && iOS 18.4 | iOS 17.4 | iOS 18.4 | |----------|----------| | <video src="https://github.com/user-attachments/assets/5c167003-f5af-4989-87c7-d09b8d3b7b81"> | <video src="https://github.com/user-attachments/assets/9c44bc1d-0956-4795-994b-2c4c314d40a7"> |
<!-- 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! ### Root Cause of the issue - Upon analysis, in iOS versions 18.4 and 18.0, GetCell is called when PopAsync is invoked—navigating back to the MainPage (which contains the CarouselView). At this point, _carouselViewLoopManager is properly set through the Setup method, and a valid IndexPath is passed into GetCell, resulting in correct updates. - However, in iOS versions 15.5 and 16.0, GetCell is triggered immediately when _viewModel.Source[0] is updated. At that time, the CarouselViewLoopManager is still null, and since a valid index cannot be retrieved, the else part of GetCell is executed with an invalid IndexPath, leading to an ArgumentNullException. ### Description of Change - To prevent ArgumentNullException caused by invalid IndexPath values during the loop initialization phase, ensure that the CarouselViewLoopManager is fully initialized before it is used. Once initialized, it correctly returns a valid IndexPath using FromRowSection, allowing the templated cell to be updated as expected in all iOS versions. ### Issues Fixed Fixes #28557 ### Tested the behaviour in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Tested Version | iOS Version | App Crashed | |----------|----------| | 15.5 | Yes | | 16.0 | Yes | | 17.4 | No | | 18.4 | No | ### Screenshot ### iOS 15.5 | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/4df6973e-c658-4c89-a085-cc2035a593bf"> | <video src="https://github.com/user-attachments/assets/25840d66-fa41-4a00-8e53-a262b405eca3"> | ### iOS 16.0 | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/882829ed-fef4-40e9-a450-2972b4134c8e"> | <video src="https://github.com/user-attachments/assets/4a5d0c48-e340-4b51-939e-6a6bf7518db7"> | ### iOS 17.4 && iOS 18.4 | iOS 17.4 | iOS 18.4 | |----------|----------| | <video src="https://github.com/user-attachments/assets/5c167003-f5af-4989-87c7-d09b8d3b7b81"> | <video src="https://github.com/user-attachments/assets/9c44bc1d-0956-4795-994b-2c4c314d40a7"> |
<!-- 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! ### Root Cause of the issue - Upon analysis, in iOS versions 18.4 and 18.0, GetCell is called when PopAsync is invoked—navigating back to the MainPage (which contains the CarouselView). At this point, _carouselViewLoopManager is properly set through the Setup method, and a valid IndexPath is passed into GetCell, resulting in correct updates. - However, in iOS versions 15.5 and 16.0, GetCell is triggered immediately when _viewModel.Source[0] is updated. At that time, the CarouselViewLoopManager is still null, and since a valid index cannot be retrieved, the else part of GetCell is executed with an invalid IndexPath, leading to an ArgumentNullException. ### Description of Change - To prevent ArgumentNullException caused by invalid IndexPath values during the loop initialization phase, ensure that the CarouselViewLoopManager is fully initialized before it is used. Once initialized, it correctly returns a valid IndexPath using FromRowSection, allowing the templated cell to be updated as expected in all iOS versions. ### Issues Fixed Fixes #28557 ### Tested the behaviour in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Tested Version | iOS Version | App Crashed | |----------|----------| | 15.5 | Yes | | 16.0 | Yes | | 17.4 | No | | 18.4 | No | ### Screenshot ### iOS 15.5 | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/4df6973e-c658-4c89-a085-cc2035a593bf"> | <video src="https://github.com/user-attachments/assets/25840d66-fa41-4a00-8e53-a262b405eca3"> | ### iOS 16.0 | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/882829ed-fef4-40e9-a450-2972b4134c8e"> | <video src="https://github.com/user-attachments/assets/4a5d0c48-e340-4b51-939e-6a6bf7518db7"> | ### iOS 17.4 && iOS 18.4 | iOS 17.4 | iOS 18.4 | |----------|----------| | <video src="https://github.com/user-attachments/assets/5c167003-f5af-4989-87c7-d09b8d3b7b81"> | <video src="https://github.com/user-attachments/assets/9c44bc1d-0956-4795-994b-2c4c314d40a7"> |
## CollectionView - Fixed the NRE in CarouselViewController on iOS 15.5 & 16.4 by @Ahamed-Ali in #30838 <details> <summary>🔧 Fixes</summary> - [NRE in CarouselViewController on iOS 15.5 & 16.4](#28557) </details> - [iOS, macOS] Fixed CollectionView group header size changes with ItemSizingStrategy by @NanthiniMahalingam in #33161 <details> <summary>🔧 Fixes</summary> - [[NET 10] I6_Grouping - Grouping_with_variable_sized_items changing the 'ItemSizingStrategy' also changes the header size.](#33130) </details> ## Flyout - Add unit tests for TabBar and FlyoutItem navigation ApplyQueryAttributes (#25663) by @StephaneDelcroix in #33006 ## Flyoutpage - Fixed the FlyoutPage.Flyout Disappearing When Maximizing the Window on Mac Platform by @NanthiniMahalingam in #26701 <details> <summary>🔧 Fixes</summary> - [FlyoutPage.Flyout - navigation corrupted when running om mac , on window ok](#22719) </details> ## Mediapicker - [Windows] Fix for PickPhotosAsync throws exception if image is modified by @HarishwaranVijayakumar in #32952 <details> <summary>🔧 Fixes</summary> - [PickPhotosAsync throws exception if image is modified.](#32408) </details> ## Navigation - Fix for TabBar Navigation does not invoke its IQueryAttributable.ApplyQueryAttributes(query) by @SuthiYuvaraj in #25663 <details> <summary>🔧 Fixes</summary> - [Tabs defined in AppShell.xaml does not invoke its view model's IQueryAttributable.ApplyQueryAttributes(query) implementaion](#13537) - [`ShellContent` routes do not call `ApplyQueryAttributes`](#28453) </details> ## ScrollView - Fix ScrollToPosition.Center behavior in ScrollView on iOS and MacCatalyst by @devanathan-vaithiyanathan in #26825 <details> <summary>🔧 Fixes</summary> - [ScrollToPosition.Center Centers the First Item too in iOS and Catalyst](#26760) - [On iOS - ScrollView.ScrollToAsync Element, ScrollToPosition.MakeVisible shifts view to the right, instead of just scrolling vertically](#28965) </details> ## Searchbar - [iOS, Mac, Windows] Fixed CharacterSpacing for SearchBar text and placeholder text by @Dhivya-SF4094 in #30407 <details> <summary>🔧 Fixes</summary> - [[iOS, Mac, Windows] SearchBar CharacterSpacing property is not working as expected](#30366) </details> ## Shell - Update logic for large title display mode on iOS - shell by @kubaflo in #33039 ## TitleView - [iOS] Fixed memory leak with PopToRootAsync when using TitleView by @Vignesh-SF3580 in #28547 <details> <summary>🔧 Fixes</summary> - [NavigationPage.TitleView causes memory leak with PopToRootAsync](#28201) </details> ## Xaml - [C] Fix binding to interface-inherited properties like IReadOnlyList<T>.Count by @StephaneDelcroix in #32912 <details> <summary>🔧 Fixes</summary> - [Compiled Binding to Array.Count provides no result](#13872) </details> - Fix #31939: CommandParameter TemplateBinding lost during reparenting by @StephaneDelcroix in #32961 <details> <summary>🔧 Fixes</summary> - [CommandParameter TemplateBinding Lost During ControlTemplate Reparenting](#31939) </details> <details> <summary>🧪 Testing (4)</summary> - [Testing] Fixed Test case failure in PR 33185 - [12/22/2025] Candidate by @TamilarasanSF4853 in #33257 - [Testing] Re-saved ShouldFlyoutBeVisibleAfterMaximizingWindow test case images in PR 33185 - [12/22/2025] Candidate by @TamilarasanSF4853 in #33271 - [Testing] Fixed Test case failure in PR 33185 - [12/22/2025] Candidate - 2 by @TamilarasanSF4853 in #33299 - [Testing] Fixed Test case failure in PR 33185 - [12/22/2025] Candidate - 3 by @TamilarasanSF4853 in #33311 </details> <details> <summary>📦 Other (2)</summary> - [XSG][BindingSourceGen] Add support for RelayCommand to compiled bindings by @simonrozsival via @Copilot in #32954 <details> <summary>🔧 Fixes</summary> - [Issue #25818](#25818) </details> - Revert "Update logic for large title display mode on iOS - shell (#33039)" in cff7f35 </details> **Full Changelog**: main...inflight/candidate
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!
Root Cause of the issue
Upon analysis, in iOS versions 18.4 and 18.0, GetCell is called when PopAsync is invoked—navigating back to the MainPage (which contains the CarouselView). At this point, _carouselViewLoopManager is properly set through the Setup method, and a valid IndexPath is passed into GetCell, resulting in correct updates.
However, in iOS versions 15.5 and 16.0, GetCell is triggered immediately when _viewModel.Source[0] is updated. At that time, the CarouselViewLoopManager is still null, and since a valid index cannot be retrieved, the else part of GetCell is executed with an invalid IndexPath, leading to an ArgumentNullException.
Description of Change
Issues Fixed
Fixes #28557
Tested the behaviour in the following platforms
Tested Version
Screenshot
iOS 15.5
CrashiniOS15.5.mov
FixedinIOS15.5.mov
iOS 16.0
CrashiniOS16.0.mov
FixediniOS16.0.mov
iOS 17.4 && iOS 18.4
NoCrashiniOS17.4.mov
NoCrashiniOS18.4.mov