From b7f0f99b4d37fdcd110d87c05b2ce2d025639cfb Mon Sep 17 00:00:00 2001 From: Jakub Florkowski Date: Sat, 2 Mar 2024 15:32:42 +0100 Subject: [PATCH] [iOS] Shell/NavigationPage TitleView (#5063) --- .../NavigationPage/iOS/NavigationRenderer.cs | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs b/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs index 61f6fece69ed..2832dff39d2e 100644 --- a/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs +++ b/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs @@ -22,6 +22,7 @@ using RectangleF = CoreGraphics.CGRect; using SizeF = CoreGraphics.CGSize; using Microsoft.Maui.Platform; +using Microsoft.Maui.Layouts; namespace Microsoft.Maui.Controls.Handlers.Compatibility { @@ -1765,6 +1766,7 @@ class Container : UIView IPlatformViewHandler _child; UIImageView _icon; bool _disposed; + const int SystemMargin = 16; public Container(View view, UINavigationBar bar) : base(bar.Bounds) { @@ -1796,6 +1798,44 @@ public Container(View view, UINavigationBar bar) : base(bar.Bounds) ClipsToBounds = true; } + // A solution based on this code https://github.dev/devxoul/UINavigationItem-Margin + // responsible for removing the system margin inside the navigation bar + UIEdgeInsets CalculateUIEdgeInsets() + { + var type = UIBarButtonSystemItem.FixedSpace; + var spacer = new UIBarButtonItem(type, (_, _) => { }); + + if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0)) + { + spacer.Width = SystemMargin + 8; + } + else + { + spacer.Width = SystemMargin - 16; + } + + nfloat screenWidth = UIScreen.MainScreen.Bounds.Size.Width; + + // A margin of private class `UINavigationButton` is different from custom view + if (!UIDevice.CurrentDevice.CheckSystemVersion(11, 0) && screenWidth < 375) + { + // 3.5 and 4 inch + spacer.Width += 8; + } + else if (screenWidth >= 414) + { + // 5.5 inch + spacer.Width -= 4; + } + + return new UIEdgeInsets(0, spacer.Width, 0, spacer.Width); + } + + public override UIEdgeInsets AlignmentRectInsets + { + get => CalculateUIEdgeInsets(); + } + void OnTitleViewParentSet(object sender, EventArgs e) { if (sender is View view) @@ -1892,10 +1932,16 @@ public override void LayoutSubviews() if (_icon != null) _icon.Frame = new RectangleF(0, 0, IconWidth, Math.Min(toolbarHeight, IconHeight)); - if (_child?.VirtualView != null) + if (_child?.VirtualView is IView view) { Rect layoutBounds = new Rect(IconWidth, 0, Bounds.Width - IconWidth, height); + if (view.HorizontalLayoutAlignment != Primitives.LayoutAlignment.Fill || + view.VerticalLayoutAlignment != Primitives.LayoutAlignment.Fill) + { + view.Measure(Bounds.Width, Bounds.Height); + layoutBounds = view.ComputeFrame(new Rect(0, 0, Bounds.Width, Bounds.Height)); + } _child.PlatformArrangeHandler(layoutBounds); } else if (_icon != null && Superview != null)