Repository: dotnet/maui
Pull request #26153: Don’t call NSAttributedString with HTML from a background thread
Author: login: kubaflo
Labels: name: area-controls-collectionview
description: CollectionView, CarouselView, IndicatorView
name: community ✨
description: Community Contribution
name: partner/syncfusion/review
Created: 2024-11-27T12:20:07Z | Merged: 2025-05-30T21:58:40Z

According to Apple's documentation: https://developer.apple.com/documentation/foundation/nsattributedstring/1524613-initwithdata

> Don’t call this method from a background thread if the options dictionary includes the [NSDocumentTypeDocumentAttribute](https://developer.apple.com/documentation/uikit/nsdocumenttypedocumentattribute) attribute with a value of [NSHTMLTextDocumentType](https://developer.apple.com/documentation/uikit/nshtmltextdocumenttype). If you do, the method tries to synchronize with the main thread, fails, and times out. Calling it from the main thread works, but can still time out if the HTML contains references to external resources. The HTML import mechanism is meant for implementing something like markdown (that is, text styles, colors, and so on), not for general HTML import.

Also, it seems to be a common problem among Apple developers:
https://forums.developer.apple.com/forums/thread/115405


### Issues Fixed

Fixes https://github.com/dotnet/maui/issues/25946

|Before|After|
|--|--|
|<video src="https://github.com/user-attachments/assets/21af7336-8df7-44a1-aa8f-4a27d2cf2579" width="300px"/>|<video width="300px" src="https://github.com/user-attachments/assets/449c911a-0ceb-4d26-a086-88be87dee3c3" />|


Diff:
diff --git a/src/Controls/src/Core/Label/Label.iOS.cs b/src/Controls/src/Core/Label/Label.iOS.cs
index 210da6315564..b57efccbd65f 100644
--- a/src/Controls/src/Core/Label/Label.iOS.cs
+++ b/src/Controls/src/Core/Label/Label.iOS.cs
@@ -36,19 +36,17 @@ public static void MapMaxLines(ILabelHandler handler, Label label)
 			handler.PlatformView?.UpdateMaxLines(label);
 		}
 
-		static void MapFormatting(ILabelHandler handler, Label label)
+		internal static void MapFormatting(ILabelHandler handler, Label label)
 		{
-			// we need to re-apply color and font for HTML labels
-			if (!label.HasFormattedTextSpans && label.TextType == TextType.Html)
+			if (IsPlainText(label))
+			{
+				LabelHandler.MapFormatting(handler, label);
+			}
+			else
 			{
 				handler.UpdateValue(nameof(ILabel.TextColor));
 				handler.UpdateValue(nameof(ILabel.Font));
 			}
-
-			if (!IsPlainText(label))
-				return;
-
-			LabelHandler.MapFormatting(handler, label);
 		}
 
 		void RecalculateSpanPositions(Size size)
diff --git a/src/Controls/src/Core/Platform/iOS/Extensions/LabelExtensions.cs b/src/Controls/src/Core/Platform/iOS/Extensions/LabelExtensions.cs
index f0a94c7b2ff4..4e22c982db10 100644
--- a/src/Controls/src/Core/Platform/iOS/Extensions/LabelExtensions.cs
+++ b/src/Controls/src/Core/Platform/iOS/Extensions/LabelExtensions.cs
@@ -14,7 +14,22 @@ public static void UpdateText(this UILabel platformLabel, Label label)
 			switch (label.TextType)
 			{
 				case TextType.Html:
-					platformLabel.UpdateTextHtml(label);
+					// NOTE: Setting HTML text this will crash with some sort of consistency error.
+					// https://github.com/dotnet/maui/issues/25946
+					// Here we have to dispatch back the the main queue to avoid the crash.
+					// This is observed with CarouselView 1 but not with 2, so hopefully this
+					// will be just disappear once we switch.
+					CoreFoundation.DispatchQueue.MainQueue.DispatchAsync(() =>
+					{
+						platformLabel.UpdateTextHtml(label);
+
+						if (label.Handler is LabelHandler labelHandler)
+							Label.MapFormatting(labelHandler, label);
+
+						// NOTE: Because we are updating text outside the normal layout
+						// pass, we need to invalidate the measure for the next pass.
+						label.InvalidateMeasure();
+					});
 					break;
 
 				default:
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue25946.xaml b/src/Controls/tests/TestCases.HostApp/Issues/Issue25946.xaml
new file mode 100644
index 000000000000..3b619185db62
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue25946.xaml
@@ -0,0 +1,34 @@
+﻿<?xml version="1.0" encoding="utf-8" ?>
+<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
+             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+             x:Class="Maui.Controls.Sample.Issues.Issue25946">
+    <Grid RowDefinitions="*,Auto">
+        <CarouselView x:Name="collectionView">
+            <CarouselView.ItemsSource>
+                <x:Array Type="{x:Type x:String}">
+                    <x:String>Item1</x:String>
+                    <x:String>Item2</x:String>
+                    <x:String>Item3</x:String>
+                </x:Array>
+            </CarouselView.ItemsSource>
+            <CarouselView.ItemTemplate>
+                <DataTemplate>
+                    <ContentView>
+                        <VerticalStackLayout HorizontalOptions="Center"
+                                             WidthRequest="200"
+                                             HeightRequest="200"
+                                             Background="Green">
+                            <Label Text="{Binding .}"/>
+                            <Label Text="{Binding .}"
+                                   TextType="Html"/>
+                        </VerticalStackLayout>
+                    </ContentView>
+                </DataTemplate>
+            </CarouselView.ItemTemplate>
+        </CarouselView>
+        <Button Grid.Row="1"
+                AutomationId="btnScrollToLastItem"
+                Clicked="ButtonClicked"
+                Text="Scroll to last Item"/>
+    </Grid>
+</ContentPage>
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue25946.xaml.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue25946.xaml.cs
new file mode 100644
index 000000000000..89372807b68d
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue25946.xaml.cs
@@ -0,0 +1,16 @@
+﻿namespace Maui.Controls.Sample.Issues
+{
+	[Issue(IssueTracker.Github, 25946, "App crashes on iOS 18 when placing html label in carousel view with > 2 elements", PlatformAffected.iOS)]
+	public partial class Issue25946 : ContentPage
+	{
+		public Issue25946()
+		{
+			InitializeComponent();
+		}
+
+		void ButtonClicked(object sender, EventArgs e)
+		{
+			collectionView.ScrollTo(1, animate: true);
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue25946.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue25946.cs
new file mode 100644
index 000000000000..0dec7b1e44d6
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue25946.cs
@@ -0,0 +1,26 @@
+﻿using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues
+{
+	public class Issue25946 : _IssuesUITest
+	{
+		public Issue25946(TestDevice testDevice) : base(testDevice)
+		{
+		}
+
+		public override string Issue => "App crashes on iOS 18 when placing html label in carousel view with > 2 elements";
+
+		[Test]
+		[Category(UITestCategories.CarouselView)]
+		[Category(UITestCategories.Label)]
+		public void AppShouldNotCrash()
+		{
+			App.WaitForElement("btnScrollToLastItem");
+			App.Click("btnScrollToLastItem");
+
+			App.WaitForElement("Item2");
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/Core/src/Platform/iOS/LabelExtensions.cs b/src/Core/src/Platform/iOS/LabelExtensions.cs
index b853b859540f..88246fe3c832 100644
--- a/src/Core/src/Platform/iOS/LabelExtensions.cs
+++ b/src/Core/src/Platform/iOS/LabelExtensions.cs
@@ -88,6 +88,14 @@ internal static void UpdateTextHtml(this UILabel platformLabel, ILabel label)
 			};
 
 			NSError nsError = new();
+
+			// NOTE: Sometimes this will crash with some sort of consistency error.
+			// https://github.com/dotnet/maui/issues/25946
+			// The caller should ensure that this extension is dispatched. We cannot
+			// do it here as we need to re-apply the formatting and we cannot call
+			// into Controls from Core.
+			// This is observed with CarouselView 1 but not with 2, so hopefully this
+			// will be just disappear once we switch.
 #pragma warning disable CS8601
 			platformLabel.AttributedText = new NSAttributedString(text, attr, ref nsError);
 #pragma warning restore CS8601


Reviews:
user: login: rmarinho
body: Nop, not from the top of my mind, can we rebase, see if it's still a issue and also add a test case for this ?
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2024-12-10T10:35:33Z
user: login: rmarinho
body: Failing tests on iOS not related 
state: DISMISSED
author_association: MEMBER
submitted_at: 2024-12-13T14:47:02Z
user: login: PureWeen
state: DISMISSED
author_association: MEMBER
submitted_at: 2024-12-13T20:55:44Z
user: login: copilot-pull-request-reviewer[bot]
body: Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.



state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2024-12-13T21:41:34Z
user: login: copilot-pull-request-reviewer[bot]
body: Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

<details>
<summary>Comments suppressed due to low confidence (1)</summary>

**src/Core/src/Platform/iOS/LabelExtensions.cs:93**
* The NSError variable nsError is not checked after the NSAttributedString initialization. Add a check for nsError and handle any errors appropriately.
```
platformLabel.AttributedText = new NSAttributedString(text, attr, ref nsError);
```
</details>


state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2024-12-13T21:51:03Z
user: login: copilot-pull-request-reviewer[bot]
body: Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

<details>
<summary>Comments suppressed due to low confidence (1)</summary>

**src/Core/src/Platform/iOS/LabelExtensions.cs:93**
* Check and handle nsError after assigning NSAttributedString to ensure any errors are properly managed.
```
platformLabel.AttributedText = new NSAttributedString(text, attr, ref nsError);
```
</details>


state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2024-12-13T21:52:06Z
user: login: kubaflo
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2024-12-13T23:46:32Z
user: login: kubaflo
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2024-12-14T00:00:33Z
user: login: mattleibow
body: Added some comment, but I just want to check. How do we know this is on a background thread? All UIKit operations are on a main thread - in fact, all of our handlers are on a main thread.

Something has gone horribly wrong if a handler mapper is updating the UI from a background thread. Where did it switch and why? 

I assume this only happens in CV, so this may be some weird case where the CV is moving to a background thread... to update the UI? Feels very sus.
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-01-10T09:39:28Z
user: login: copilot-pull-request-reviewer[bot]
body: ## Pull Request Overview

Addresses an iOS crash by ensuring HTML-based `NSAttributedString` initialization runs on the main thread and re-applies formatting afterward.

- Dispatch HTML label creation to the main queue and invalidate measurement.
- Introduced `ReapplyFormattingForHTMLLabel` to reapply color and font after HTML updates.
- Removed redundant HTML formatting logic from the default `MapFormatting` path and added a UI test for the scenario.

### Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

<details>
<summary>Show a summary per file</summary>

| File                                           | Description                                                         |
|------------------------------------------------|---------------------------------------------------------------------|
| src/Core/src/Platform/iOS/LabelExtensions.cs    | Wraps HTML `NSAttributedString` init in a main-thread dispatch and re-applies formatting. |
| src/Core/src/Handlers/Label/LabelHandler.iOS.cs | Adds `ReapplyFormattingForHTMLLabel` to update color and font after HTML rendering. |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue25946.cs      | New UI test to scroll a carousel and verify no crash with HTML labels. |
| src/Controls/tests/TestCases.HostApp/Issues/Issue25946.xaml(.cs)          | Sample page and code behind demonstrating the crash scenario.      |
| src/Controls/src/Core/Label/Label.iOS.cs         | Removes now-unneeded HTML formatting reapplication in `MapFormatting`. |
</details>





state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-23T02:02:15Z
user: login: mattleibow
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-23T02:02:44Z
user: login: mattleibow
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-23T02:03:21Z
user: login: mattleibow
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-23T02:47:43Z
user: login: copilot-pull-request-reviewer[bot]
body: ## Pull Request Overview

This PR addresses crashes occurring when converting HTML to NSAttributedString on a background thread by dispatching the conversion to the main queue. It also adds test cases to validate that the crash is avoided.
- Dispatch HTML text conversion to the main thread in both LabelExtensions implementations
- Update Label formatting logic for HTML labels in iOS
- Add automated tests to cover the issue

### Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

<details>
<summary>Show a summary per file</summary>

| File | Description |
| ---- | ----------- |
| src/Core/src/Platform/iOS/LabelExtensions.cs | Added explanatory comments about potential crash and ensured NSAttributedString creation is maintained (note only comment updates) |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue25946.cs | Added a test case to verify the app does not crash |
| src/Controls/tests/TestCases.HostApp/Issues/Issue25946.xaml.cs | Implements a test host page for the issue |
| src/Controls/tests/TestCases.HostApp/Issues/Issue25946.xaml | Updated XAML definitions to support and trigger the test |
| src/Controls/src/Core/Platform/iOS/Extensions/LabelExtensions.cs | Wrapped HTML text updates in a DispatchQueue.MainQueue block to ensure main thread execution |
| src/Controls/src/Core/Label/Label.iOS.cs | Changed MapFormatting from private to internal and simplified its logic |
</details>



<details>
<summary>Comments suppressed due to low confidence (1)</summary>

**src/Controls/src/Core/Label/Label.iOS.cs:39**
* Changing the access modifier of MapFormatting to internal alters the API's exposure. Please verify that this change is intentional and will not introduce breaking changes for internal consumers.
```
internal static void MapFormatting(ILabelHandler handler, Label label)
```
</details>


state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-23T02:51:46Z
user: login: mattleibow
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-30T21:56:51Z

Review comments:
diff_hunk: @@ -88,9 +88,16 @@ internal static void UpdateTextHtml(this UILabel platformLabel, ILabel label)
 			};
 
 			NSError nsError = new();
-#pragma warning disable CS8601
-			platformLabel.AttributedText = new NSAttributedString(text, attr, ref nsError);
-#pragma warning restore CS8601
+			CoreFoundation.DispatchQueue.MainQueue.DispatchAsync(() =>
path: src/Core/src/Platform/iOS/LabelExtensions.cs
user: login: PureWeen
body: I might not be following your description quite right but should we check if we're on a background thread before dispatching? 
created_at: 2024-12-13T20:55:13Z
author_association: MEMBER
diff_hunk: @@ -88,9 +88,16 @@ internal static void UpdateTextHtml(this UILabel platformLabel, ILabel label)
 			};
 
 			NSError nsError = new();
-#pragma warning disable CS8601
-			platformLabel.AttributedText = new NSAttributedString(text, attr, ref nsError);
-#pragma warning restore CS8601
+			CoreFoundation.DispatchQueue.MainQueue.DispatchAsync(() =>
+			{
+				platformLabel.AttributedText = new NSAttributedString(text, attr, ref nsError);
+				if (label.Handler is ILabelHandler labelHandler)
+				{
+					labelHandler.UpdateValue(nameof(ILabel.TextColor));
+					labelHandler.UpdateValue(nameof(ILabel.Font));
+				}
+				label.InvalidateMeasure();
path: src/Core/src/Platform/iOS/LabelExtensions.cs
user: login: PureWeen
body: What happens if we don't include this?
created_at: 2024-12-13T20:55:23Z
author_association: MEMBER
diff_hunk: @@ -88,9 +88,16 @@ internal static void UpdateTextHtml(this UILabel platformLabel, ILabel label)
 			};
 
 			NSError nsError = new();
-#pragma warning disable CS8601
-			platformLabel.AttributedText = new NSAttributedString(text, attr, ref nsError);
-#pragma warning restore CS8601
+			CoreFoundation.DispatchQueue.MainQueue.DispatchAsync(() =>
+			{
+				platformLabel.AttributedText = new NSAttributedString(text, attr, ref nsError);
+				if (label.Handler is ILabelHandler labelHandler)
+				{
+					labelHandler.UpdateValue(nameof(ILabel.TextColor));
+					labelHandler.UpdateValue(nameof(ILabel.Font));
+				}
+				label.InvalidateMeasure();
path: src/Core/src/Platform/iOS/LabelExtensions.cs
user: login: kubaflo
body: Without `label.InvalidateMeasure();` the label doesn't render
created_at: 2024-12-13T23:46:31Z
author_association: CONTRIBUTOR
diff_hunk: @@ -88,9 +88,16 @@ internal static void UpdateTextHtml(this UILabel platformLabel, ILabel label)
 			};
 
 			NSError nsError = new();
-#pragma warning disable CS8601
-			platformLabel.AttributedText = new NSAttributedString(text, attr, ref nsError);
-#pragma warning restore CS8601
+			CoreFoundation.DispatchQueue.MainQueue.DispatchAsync(() =>
path: src/Core/src/Platform/iOS/LabelExtensions.cs
user: login: kubaflo
body: With something like this:

```c#
NSError nsError = new();
if (NSThread.IsMain)
{
	platformLabel.AttributedText = new NSAttributedString(text, attr, ref nsError);
	if (label.Handler is ILabelHandler labelHandler)
	{
		labelHandler.UpdateValue(nameof(ILabel.TextColor));
		labelHandler.UpdateValue(nameof(ILabel.Font));
	}
	label.InvalidateMeasure();
}
else
{
	CoreFoundation.DispatchQueue.MainQueue.DispatchAsync(() =>
	{
		platformLabel.AttributedText = new NSAttributedString(text, attr, ref nsError);
		if (label.Handler is ILabelHandler labelHandler)
		{
			labelHandler.UpdateValue(nameof(ILabel.TextColor));
			labelHandler.UpdateValue(nameof(ILabel.Font));
		}
		label.InvalidateMeasure();
	});
}
```

The list view/collection view with the HTML label looks right, but the app crashes when using the collection view
<img width="1454" alt="Screenshot 2024-12-14 at 00 59 02" src="https://github.com/user-attachments/assets/e4b46448-45fc-4df6-810d-6abc1771282f" />

created_at: 2024-12-14T00:00:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -88,9 +88,16 @@ internal static void UpdateTextHtml(this UILabel platformLabel, ILabel label)
 			};
 
 			NSError nsError = new();
-#pragma warning disable CS8601
-			platformLabel.AttributedText = new NSAttributedString(text, attr, ref nsError);
-#pragma warning restore CS8601
+			CoreFoundation.DispatchQueue.MainQueue.DispatchAsync(() =>
path: src/Core/src/Platform/iOS/LabelExtensions.cs
user: login: mattleibow
body: Maybe use a local function to avoid code duplication.
created_at: 2025-01-10T09:33:58Z
author_association: MEMBER
diff_hunk: @@ -38,13 +38,6 @@ public static void MapMaxLines(ILabelHandler handler, Label label)
 
 		static void MapFormatting(ILabelHandler handler, Label label)
path: src/Controls/src/Core/Label/Label.iOS.cs
user: login: mattleibow
body: I feel like I wrote this code and overengineered this. It appears there is just 1 usage of the MapFormatting method, and it was already weird. Maybe this should just be merged with the MapText or UpdateText?
created_at: 2025-01-10T09:36:05Z
author_association: MEMBER
diff_hunk: @@ -88,9 +88,16 @@ internal static void UpdateTextHtml(this UILabel platformLabel, ILabel label)
 			};
 
 			NSError nsError = new();
-#pragma warning disable CS8601
-			platformLabel.AttributedText = new NSAttributedString(text, attr, ref nsError);
-#pragma warning restore CS8601
+			CoreFoundation.DispatchQueue.MainQueue.DispatchAsync(() =>
path: src/Core/src/Platform/iOS/LabelExtensions.cs
user: login: mattleibow
body: Will the async cause issues because that would be unexpected? Will DispatchSync work/have issues/locking?
created_at: 2025-01-10T09:37:05Z
author_association: MEMBER
diff_hunk: @@ -88,9 +88,16 @@ internal static void UpdateTextHtml(this UILabel platformLabel, ILabel label)
 			};
 
 			NSError nsError = new();
-#pragma warning disable CS8601
-			platformLabel.AttributedText = new NSAttributedString(text, attr, ref nsError);
-#pragma warning restore CS8601
+			CoreFoundation.DispatchQueue.MainQueue.DispatchAsync(() =>
+			{
+				platformLabel.AttributedText = new NSAttributedString(text, attr, ref nsError);
+				if (label.Handler is ILabelHandler labelHandler)
+				{
+					labelHandler.UpdateValue(nameof(ILabel.TextColor));
+					labelHandler.UpdateValue(nameof(ILabel.Font));
+				}
path: src/Core/src/Platform/iOS/LabelExtensions.cs
user: login: mattleibow
body: Not sure if using handlers here is expected... Not sure if that is bad or good, but in my mind all the handler things happen in the handler or close to it. This is a few methods away now so may be surprising.
created_at: 2025-01-10T09:37:09Z
author_association: MEMBER
diff_hunk: @@ -88,9 +88,16 @@ internal static void UpdateTextHtml(this UILabel platformLabel, ILabel label)
 			};
 
 			NSError nsError = new();
-#pragma warning disable CS8601
-			platformLabel.AttributedText = new NSAttributedString(text, attr, ref nsError);
-#pragma warning restore CS8601
+			CoreFoundation.DispatchQueue.MainQueue.DispatchAsync(() =>
path: src/Core/src/Platform/iOS/LabelExtensions.cs
user: login: mattleibow
body: It is already on the main thread and main queue. Not sure why it fails. At this point the crash is more of an issue.

created_at: 2025-05-23T02:02:44Z
author_association: MEMBER
diff_hunk: @@ -88,9 +88,16 @@ internal static void UpdateTextHtml(this UILabel platformLabel, ILabel label)
 			};
 
 			NSError nsError = new();
-#pragma warning disable CS8601
-			platformLabel.AttributedText = new NSAttributedString(text, attr, ref nsError);
-#pragma warning restore CS8601
+			CoreFoundation.DispatchQueue.MainQueue.DispatchAsync(() =>
+			{
+				platformLabel.AttributedText = new NSAttributedString(text, attr, ref nsError);
+				if (label.Handler is ILabelHandler labelHandler)
+				{
+					labelHandler.UpdateValue(nameof(ILabel.TextColor));
+					labelHandler.UpdateValue(nameof(ILabel.Font));
+				}
+				label.InvalidateMeasure();
path: src/Core/src/Platform/iOS/LabelExtensions.cs
user: login: mattleibow
body: Yeah, this is basically a Post for android. Puts it at the top of the queue - after the layout has run.
created_at: 2025-05-23T02:03:20Z
author_association: MEMBER

PR comments:
user: login: rmarinho
created_at: 2024-11-27T14:19:58Z
body: /azp run
author_association: MEMBER
user: login: azure-pipelines[bot]
created_at: 2024-11-27T14:20:20Z
body: <samp>
Azure Pipelines successfully started running 3 pipeline(s).<br>

</samp>
author_association: NONE
user: login: kubaflo
created_at: 2024-11-27T19:58:27Z
body: I now noticed that the crash happens with `CarouselView1` only when swiping between more than 2 items, but in the case of `CarouselView2` the app crashes instantly when `CarouselView2` has more than 1 item

```
<CarouselView Grid.Row="1">
    <CarouselView.ItemsSource>
        <x:Array Type="{x:Type x:String}">
            <x:String>Item1</x:String>
            <x:String>Item2</x:String>
        </x:Array>
    </CarouselView.ItemsSource>
    <CarouselView.ItemTemplate>
        <DataTemplate>
            <VerticalStackLayout Background="Red">
                <Label Text="Hello"/>
                <Label Text="{Binding .}"
                        TextType="Html"/>
            </VerticalStackLayout>
        </DataTemplate>
    </CarouselView.ItemTemplate>
</CarouselView>
```
author_association: CONTRIBUTOR
user: login: kubaflo
created_at: 2024-11-27T20:04:04Z
body: Ohh I just bumped into a scaling issue with ListView/CollectionView1 and CollectionView1 after changes in this PR:

For the following code: 
```
<Grid RowDefinitions="*,*">
    <CollectionView>
        <CollectionView.ItemsSource>
            <x:Array Type="{x:Type x:String}">
                <x:String>Item1</x:String>
                <x:String>Item1</x:String>
                <x:String>Item1</x:String>
            </x:Array>
        </CollectionView.ItemsSource>
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <VerticalStackLayout>
                    <Label Text="Hello"/>
                    <Label Text="{Binding .}"
                            TextType="Html"/>
                </VerticalStackLayout>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>

    <StackLayout Grid.Row="1">
        <BindableLayout.ItemsSource>
            <x:Array Type="{x:Type x:String}">
                <x:String>Item1</x:String>
                <x:String>Item1</x:String>
                <x:String>Item1</x:String>
            </x:Array>
        </BindableLayout.ItemsSource>
        <BindableLayout.ItemTemplate>
            <DataTemplate>
                <VerticalStackLayout>
                    <Label Text="Hello"/>
                    <Label Text="{Binding .}"
                            TextType="Html"/>
                </VerticalStackLayout>
            </DataTemplate>
        </BindableLayout.ItemTemplate>
    </StackLayout>
</Grid>
```
I have a cell scaling issue
<img width="300px" src="https://github.com/user-attachments/assets/32bfe4bf-e3e4-477e-997f-68639b58d549"/>

It gets automatically fixed after updating any of the Label's properties
@rmarinho do you maybe have an idea why it happens?

author_association: CONTRIBUTOR
user: login: kubaflo
created_at: 2024-12-10T13:09:03Z
body: > Nop, not from the top of my mind, can we rebase, see if it's still a issue and also add a test case for this ?

I've rebased, but the issue is still there without using `MainQueue.DispatchAsync`
However, I'm not sure if it is a correct fix, because it still regresses the height of HTML text in listView and cv
author_association: CONTRIBUTOR
user: login: rmarinho
created_at: 2024-12-11T09:21:34Z
body: /azp run
author_association: MEMBER
user: login: azure-pipelines[bot]
created_at: 2024-12-11T09:21:56Z
body: <samp>
Azure Pipelines successfully started running 3 pipeline(s).<br>

</samp>
author_association: NONE
user: login: kubaflo
created_at: 2024-12-17T19:21:04Z
body: > <Grid RowDefinitions="*,*">
>     <CollectionView>
>         <CollectionView.ItemsSource>
>             <x:Array Type="{x:Type x:String}">
>                 <x:String>Item1</x:String>
>                 <x:String>Item1</x:String>
>                 <x:String>Item1</x:String>
>             </x:Array>
>         </CollectionView.ItemsSource>
>         <CollectionView.ItemTemplate>
>             <DataTemplate>
>                 <VerticalStackLayout>
>                     <Label Text="Hello"/>
>                     <Label Text="{Binding .}"
>                             TextType="Html"/>
>                 </VerticalStackLayout>
>             </DataTemplate>
>         </CollectionView.ItemTemplate>
>     </CollectionView>
> 
>     <StackLayout Grid.Row="1">
>         <BindableLayout.ItemsSource>
>             <x:Array Type="{x:Type x:String}">
>                 <x:String>Item1</x:String>
>                 <x:String>Item1</x:String>
>                 <x:String>Item1</x:String>
>             </x:Array>
>         </BindableLayout.ItemsSource>
>         <BindableLayout.ItemTemplate>
>             <DataTemplate>
>                 <VerticalStackLayout>
>                     <Label Text="Hello"/>
>                     <Label Text="{Binding .}"
>                             TextType="Html"/>
>                 </VerticalStackLayout>
>             </DataTemplate>
>         </BindableLayout.ItemTemplate>
>     </StackLayout>
> </Grid>

I tested and this is fixed with this PR: https://github.com/dotnet/maui/pull/25664 But, I believe @albyrock87 divided it into smaller ones 
author_association: CONTRIBUTOR
user: login: jfversluis
created_at: 2024-12-18T08:40:53Z
body: /azp run 
author_association: MEMBER
user: login: azure-pipelines[bot]
created_at: 2024-12-18T08:41:16Z
body: <samp>
Azure Pipelines successfully started running 3 pipeline(s).<br>

</samp>
author_association: NONE
user: login: jfversluis
created_at: 2025-01-09T10:59:28Z
body: /rebase
author_association: MEMBER
user: login: azure-pipelines[bot]
created_at: 2025-01-09T11:02:27Z
body: <samp>
Azure Pipelines successfully started running 3 pipeline(s).<br>

</samp>
author_association: NONE
user: login: jfversluis
created_at: 2025-01-14T14:51:59Z
body: @kubaflo some comments!
author_association: MEMBER
user: login: kubaflo
created_at: 2025-01-14T16:13:08Z
body: @mattleibow I've refactored a bit
author_association: CONTRIBUTOR
user: login: rmarinho
created_at: 2025-01-14T16:14:22Z
body: /azp run 
author_association: MEMBER
user: login: azure-pipelines[bot]
created_at: 2025-01-14T16:14:45Z
body: <samp>
Azure Pipelines successfully started running 3 pipeline(s).<br>

</samp>
author_association: NONE
user: login: jsuarezruiz
created_at: 2025-02-19T07:32:44Z
body: /rebase
author_association: CONTRIBUTOR
user: login: jsuarezruiz
created_at: 2025-03-13T09:14:56Z
body: /rebase
author_association: CONTRIBUTOR
user: login: PureWeen
created_at: 2025-03-19T18:56:39Z
body: /rebase
author_association: MEMBER
user: login: mattleibow
created_at: 2025-05-23T00:52:16Z
body: @kubaflo I cant repro this with CV2:

<img width="993" alt="image" src="https://github.com/user-attachments/assets/f61da43f-729c-4548-9a13-4765047144b5" />


author_association: MEMBER
user: login: mattleibow
created_at: 2025-05-23T02:01:05Z
body: Investigating this and the threrad is right, just sometimes (always) it crashes. It makes no sense. The thread, dispatch queue and operation queue are all the main ones.

This does not happen with CV2 so I am a bit annoyed as to why. It might be the layout differences.
author_association: MEMBER
user: login: mattleibow
created_at: 2025-05-23T02:50:35Z
body: I moved the dispatch into Controls where the rest of the HTML things are done. One day (in my dreams) we are going to have a separate HTML label and I can just delete everything.

But for now, this is really strage.

I could only repro the crash with CV1, but who knows... So this should now be safe for CV1 and CV2. The dispatch is not abou threads or queues but rather ordering or maybe something is happening in the string init that is messing with the layout or the containing animation.

Regardless, this should be safe to merge as it is just a "post the update for after the layout".

author_association: MEMBER
user: login: mattleibow
created_at: 2025-05-23T02:50:57Z
body: /azp run MAUI-UITests-public
author_association: MEMBER
user: login: azure-pipelines[bot]
created_at: 2025-05-23T02:51:08Z
body: <samp>
Azure Pipelines successfully started running 1 pipeline(s).<br>

</samp>
author_association: NONE
user: login: mattleibow
created_at: 2025-05-23T02:51:15Z
body: Running UI tests because I want to make sure nothing else is weird.
author_association: MEMBER
user: login: mattleibow
created_at: 2025-05-30T21:51:31Z
body: /rebase
author_association: MEMBER