Skip to content

Commit

Permalink
Wait for parent to get set before realizing titleview (#17360)
Browse files Browse the repository at this point in the history
  • Loading branch information
PureWeen authored Sep 14, 2023
1 parent 96073eb commit 64d964a
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 3 deletions.
65 changes: 65 additions & 0 deletions src/Controls/samples/Controls.Sample.UITests/Issues/Issue17347.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System;
using Microsoft.Maui.Controls;

namespace Maui.Controls.Sample.Issues
{
[Issue(IssueTracker.Github, 17347, "Setting a new TitleView on an already created page crashes iOS", PlatformAffected.iOS)]
public class Issue17347 : TestContentPage
{
protected override void Init()
{
var navPage = new NavigationPage(new MainPage());
NavigatedTo += Issue16499_NavigatedTo;

async void Issue16499_NavigatedTo(object sender, NavigatedToEventArgs e)
{
NavigatedTo -= Issue16499_NavigatedTo;

await Navigation.PushModalAsync(navPage);
await navPage.Navigation.PushAsync(new MainPage());
await navPage.Navigation.PushAsync(new MainPage());
await navPage.Navigation.PopAsync();
await navPage.Navigation.PopAsync();
}
}

public partial class MainPage : ContentPage
{
Label TopView;
static int i = 0;
protected override void OnAppearing()
{
Content = new VerticalStackLayout()
{
new Button()
{
AutomationId = "PopMeButton",
Command = new Command(async () =>
{
if (Navigation.NavigationStack.Count == 1)
await Navigation.PopModalAsync();
else
await Navigation.PopAsync();
}),
Text = "Click to Pop This Page If Needed"
}
};

var increment = $"{i++}";
TopView = new()
{
AutomationId = "TitleViewLabel" + increment
};

TopView.SetBinding(Label.TextProperty, "AutomationId");
TopView.BindingContext = TopView;

TopView.WidthRequest = App.Current.Windows[0].Page.Width / 2;
NavigationPage.SetTitleView(this, TopView);
NavigationPage.SetHasNavigationBar(this, true);
NavigationPage.SetHasBackButton(this, false);
base.OnAppearing();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1759,14 +1759,40 @@ public Container(View view, UINavigationBar bar) : base(bar.Bounds)
if (view != null)
{
_view = view;
var platformView = view.ToPlatform(view.FindMauiContext());
_child = (IPlatformViewHandler)view.Handler;
AddSubview(platformView);

if (_view.Parent is null)
{
_view.ParentSet += OnTitleViewParentSet;
}
else
{
SetupTitleView();
}
}

ClipsToBounds = true;
}

void OnTitleViewParentSet(object sender, EventArgs e)
{
if (sender is View view)
view.ParentSet -= OnTitleViewParentSet;

SetupTitleView();
}

void SetupTitleView()
{
var mauiContext = _view.FindMauiContext();
if (_view is not null && mauiContext is not null)
{
var platformView = _view.ToPlatform(mauiContext);
_child = (IPlatformViewHandler)_view.Handler;
AddSubview(platformView);
}

}

public override CGSize IntrinsicContentSize => UILayoutFittingExpandedSize;

nfloat IconHeight => _icon?.Frame.Height ?? 0;
Expand Down Expand Up @@ -1874,6 +1900,11 @@ protected override void Dispose(bool disposing)
_child = null;
}

if (_view is not null)
{
_view.ParentSet -= OnTitleViewParentSet;
}

_view = null;

_icon?.Dispose();
Expand Down
29 changes: 29 additions & 0 deletions src/Controls/tests/UITests/Tests/Issues/Issue17347.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System.Drawing;
using Microsoft.Maui.Appium;
using NUnit.Framework;
using OpenQA.Selenium.Appium.MultiTouch;
using TestUtils.Appium.UITests;

namespace Microsoft.Maui.AppiumTests.Issues
{
public class Issue17347 : _IssuesUITest
{
public Issue17347(TestDevice device) : base(device)
{
}

public override string Issue => "Setting a new TitleView on an already created page crashes iOS";

[Test]
public void AppDoesntCrashWhenSettingNewTitleViewOnExistingPage() {
try
{
App.WaitForElement("TitleViewLabel4", timeout: TimeSpan.FromSeconds(4));
}
finally
{
App.Tap("PopMeButton");
}
}
}
}

0 comments on commit 64d964a

Please sign in to comment.