Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS Shell TitleView Update Height #20795

Merged
merged 2 commits into from
Feb 27, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -535,11 +535,7 @@ public override CGRect Frame

public override void LayoutSubviews()
{
if (Height == null || Height == 0)
{
UpdateFrame(Superview);
}

UpdateFrame(Superview);
base.LayoutSubviews();
}

Expand All @@ -553,9 +549,6 @@ void UpdateFrame(UIView newSuper)
{
if (newSuper is not null && newSuper.Bounds != CGRect.Empty)
{
if (!(OperatingSystem.IsIOSVersionAtLeast(11) || OperatingSystem.IsTvOSVersionAtLeast(11)))
Frame = new CGRect(Frame.X, newSuper.Bounds.Y, Frame.Width, newSuper.Bounds.Height);

Height = newSuper.Bounds.Height;
}
}
Expand Down
118 changes: 117 additions & 1 deletion src/Controls/tests/DeviceTests/Elements/Shell/ShellTests.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
using Xunit;
using static Microsoft.Maui.DeviceTests.AssertHelpers;
using ShellHandler = Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer;
using UIModalPresentationStyle = Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific.UIModalPresentationStyle;
using Microsoft.Maui.DeviceTests.Stubs;
using Microsoft.Maui.Handlers;
using Microsoft.Maui.Hosting;

namespace Microsoft.Maui.DeviceTests
{
Expand Down Expand Up @@ -281,6 +283,120 @@ await CreateHandlerAndAddToWindow<ShellHandler>(shell, async (handler) =>
});
}

[Fact(DisplayName = "TitleView can use constraints to expand area")]
public async Task TitleViewConstraints()
{
EnsureHandlerCreated(builder =>
{
builder.ConfigureMauiHandlers(handlers =>
{
SetupShellHandlers(handlers);
handlers.AddHandler(typeof(Shell), typeof(CustomShellHandler));
});
});

var shellTitleView = new VerticalStackLayout { BackgroundColor = Colors.Green };
var titleViewContent = new Label { Text = "Full Height TitleView" };
shellTitleView.Children.Add(titleViewContent);

var label = new Label { Text = "Page Content", Background = Colors.LightBlue };

var shell = await CreateShellAsync(shell =>
{
Shell.SetTitleView(shell, shellTitleView);

shell.CurrentItem = new ContentPage(){
Content = new VerticalStackLayout {
Background = Colors.Gray,
Children = { label }
}
};
});

await CreateHandlerAndAddToWindow<ShellHandler>(shell, async (handler) =>
{
await Task.Delay(50);
var titleView = GetTitleView(handler) as UIView;
var originalFrame = (handler as CustomShellHandler).PreviousFrame;
var expandedFrame = titleView.Frame;
var relativeTitleViewFrame = titleView.ConvertRectToView(titleView.Bounds, null);
var uiLabel = label.ToPlatform();
var relativeLabelFrame = uiLabel.ConvertRectToView(uiLabel.Bounds, null);

// Make sure the titleView is touching the label. Happens by default on iPhone but not on iPad
Assert.True(relativeTitleViewFrame.Bottom == relativeLabelFrame.Top);
Assert.True(expandedFrame.Width > originalFrame.Width);
});
}

class CustomShellHandler : ShellRenderer
{
protected override IShellNavBarAppearanceTracker CreateNavBarAppearanceTracker() => new CustomShellNavBarAppearanceTracker(this, base.CreateNavBarAppearanceTracker()) {handler = this};

public CGRect PreviousFrame { get; set; }
}

class CustomShellNavBarAppearanceTracker : IShellNavBarAppearanceTracker
{
readonly IShellContext _context;
readonly IShellNavBarAppearanceTracker _baseTracker;

public CGRect previousFrame { get; set; } = CGRect.Empty;

public CustomShellHandler handler { get; set; }

public CustomShellNavBarAppearanceTracker(IShellContext context, IShellNavBarAppearanceTracker baseTracker)
{
_context = context;
_baseTracker = baseTracker;
}

public void Dispose() => _baseTracker.Dispose();

public void ResetAppearance(UINavigationController controller) => _baseTracker.ResetAppearance(controller);

public void SetAppearance(UINavigationController controller, ShellAppearance appearance) => _baseTracker.SetAppearance(controller, appearance);

public void SetHasShadow(UINavigationController controller, bool hasShadow) => _baseTracker.SetHasShadow(controller, hasShadow);

public void UpdateLayout(UINavigationController controller)
{
UIView titleView = Shell.GetTitleView(_context.Shell.CurrentPage)?.Handler?.PlatformView as UIView ?? Shell.GetTitleView(_context.Shell)?.Handler?.PlatformView as UIView;

UIView parentView = GetParentByType(titleView, typeof(UIKit.UIControl));
handler.PreviousFrame = parentView.Frame;

if (parentView != null)
{
// height constraint
NSLayoutConstraint.Create(parentView, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, parentView.Superview, NSLayoutAttribute.Bottom, 1.0f, 0.0f).Active = true;
NSLayoutConstraint.Create(parentView, NSLayoutAttribute.Top, NSLayoutRelation.Equal, parentView.Superview, NSLayoutAttribute.Top, 1.0f, 0.0f).Active = true;

// width constraint
NSLayoutConstraint.Create(parentView, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, parentView.Superview, NSLayoutAttribute.Leading, 1.0f, 0.0f).Active = true;
NSLayoutConstraint.Create(parentView, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, parentView.Superview, NSLayoutAttribute.Trailing, 1.0f, 0.0f).Active = true;
}
_baseTracker.UpdateLayout(controller);
}

static UIView GetParentByType(UIView view, Type type)
{
UIView currentView = view;

while (currentView != null)
{
if (currentView.GetType().UnderlyingSystemType == type)
{
break;
}

currentView = currentView.Superview;
}

return currentView;
}
}

protected async Task OpenFlyout(ShellRenderer shellRenderer, TimeSpan? timeOut = null)
{
var flyoutView = GetFlyoutPlatformView(shellRenderer);
Expand Down
Loading