Skip to content

Commit 6b2c5f9

Browse files
authored
fix: hot reload ios support for navigationbar (#1354)
* fix: hot reload ios support for navigationbar * chore: do not render when unloaded * chore: wip * chore: wip * chore: unhook from element in renderer * chore: undo uno bump * chore: fix unloaded event unhook
1 parent 0498325 commit 6b2c5f9

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

src/Uno.Toolkit.UI/Controls/NavigationBar/NativeNavigationBarPresenter.iOS.cs

+16-2
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,12 @@ private void OnUnloaded(object sender, RoutedEventArgs e)
6060
partial void OnOwnerChanged()
6161
{
6262
// TODO: Find a proper way to decide whether a NavigationBar exists on canvas (within Page), or is mapped to the UINavigationController's NavigationBar.
63-
6463
_mainCommandClickHandler.Disposable = null;
6564

6665
if (GetNavBar() is { } navBar)
6766
{
6867
navBar.MainCommand.Click += OnMainCommandClick;
69-
68+
7069
_mainCommandClickHandler.Disposable = Disposable.Create(() => navBar.MainCommand.Click -= OnMainCommandClick);
7170

7271
LayoutNativeNavBar(navBar);
@@ -75,6 +74,21 @@ partial void OnOwnerChanged()
7574

7675
private void LayoutNativeNavBar(NavigationBar navBar)
7776
{
77+
var page = navBar.FindFirstParent<Page>();
78+
var parent = page?.Parent as Page;
79+
if (page is not null
80+
&& parent?.GetType() == page.GetType())
81+
{
82+
// Support for Hot Reload
83+
// On iOS, the current Page instance is retained and its Content is replaced with a new instance of the Page
84+
// If we detect that we have fallen into this scenario, hook up the new NavigationBar from within the new Page instance
85+
// to the native UINavigationBar and UINavigationItem instances.
86+
var vc = parent.FindViewController();
87+
88+
NavigationBarHelper.SetNavigationItem(navBar, vc.NavigationItem);
89+
NavigationBarHelper.SetNavigationBar(navBar, vc.NavigationController?.NavigationBar);
90+
}
91+
7892
if (navBar.TryGetNative<NavigationBar, NavigationBarRenderer, UINavigationBar>(out var nativeBar)
7993
&& nativeBar is { })
8094
{

src/Uno.Toolkit.UI/Controls/NavigationBar/Renderer.cs

+22
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ internal abstract class Renderer<TElement, TNative> : IDisposable
3737
where TNative : class
3838
{
3939
private CompositeDisposable _subscriptions = new CompositeDisposable();
40+
#if __IOS__
41+
private SerialDisposable _unloadedSubscription = new SerialDisposable();
42+
#endif
4043
private readonly WeakReference<TElement> _element;
4144
private TNative? _native;
4245
private bool _isRendering;
@@ -48,9 +51,28 @@ public Renderer(TElement element)
4851
throw new ArgumentNullException(nameof(element));
4952
}
5053

54+
#if __IOS__
55+
if (element is FrameworkElement fe)
56+
{
57+
fe.Unloaded += OnElementUnloaded;
58+
_unloadedSubscription.Disposable = Disposable.Create(() =>
59+
{
60+
fe.Unloaded -= OnElementUnloaded;
61+
});
62+
}
63+
#endif
64+
5165
_element = new WeakReference<TElement>(element);
5266
}
5367

68+
#if __IOS__
69+
private void OnElementUnloaded(object sender, RoutedEventArgs? e)
70+
{
71+
_unloadedSubscription.Dispose();
72+
Dispose();
73+
}
74+
#endif
75+
5476
public TElement? Element
5577
{
5678
get

0 commit comments

Comments
 (0)