Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions src/Controls/src/Core/Label/Label.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
17 changes: 16 additions & 1 deletion src/Controls/src/Core/Platform/iOS/Extensions/LabelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
34 changes: 34 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue25946.xaml
Original file line number Diff line number Diff line change
@@ -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>
16 changes: 16 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue25946.xaml.cs
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
Original file line number Diff line number Diff line change
@@ -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");
}
}
}
8 changes: 8 additions & 0 deletions src/Core/src/Platform/iOS/LabelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down