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

Fixed shell pages with top bar #20337

Closed
wants to merge 3 commits into from

Conversation

kubaflo
Copy link
Contributor

@kubaflo kubaflo commented Feb 3, 2024

Description of Change

The solution is based on the Page Rendered from Xamarin Forms

Issues Fixed

Fixes #19159

Before After
Simulator.Screen.Recording.-.iPhone.15.Pro.Max.-.2024-02-03.at.01.15.28.mp4
Simulator.Screen.Recording.-.iPhone.15.Pro.Max.-.2024-02-02.at.16.41.21.mp4

@kubaflo kubaflo requested a review from a team as a code owner February 3, 2024 00:18
@ghost ghost added the community ✨ Community Contribution label Feb 3, 2024
@ghost
Copy link

ghost commented Feb 3, 2024

Hey there @kubaflo! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed.

@jsuarezruiz
Copy link
Contributor

/azp run

Copy link

Azure Pipelines successfully started running 3 pipeline(s).

@jsuarezruiz jsuarezruiz added area-controls-shell Shell Navigation, Routes, Tabs, Flyout platform/iOS 🍎 labels Feb 5, 2024
_ = App.WaitForElement("page1");

// The content should not be overlaid by top bar
App.Screenshot();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could use here App.VerifyScreenshot?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure!. Should I change it in all my UI tests? I think I wrote App.Screenshot(); instead of VerifyScreenshot in all my PRs 😅

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It depends. If there are checks validating properties such as text, sizes, etc. is a correct additional validation. But if we are going to validate something (colors, sizes, etc.) with a screenshot, VerifyScreenshot is the correct one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@jsuarezruiz
Copy link
Contributor

/azp run

Copy link

Azure Pipelines successfully started running 3 pipeline(s).

Copy link
Member

@PureWeen PureWeen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if we can do this.

We intentionally got rid of the padding path.
With NET8 we set the additional insets

void LayoutHeader()
{
if (ShellSection == null)
return;
int tabThickness = 0;
if (_header != null)
{
tabThickness = HeaderHeight;
var headerTop = (OperatingSystem.IsIOSVersionAtLeast(11) || OperatingSystem.IsMacCatalystVersionAtLeast(11)
#if TVOS
|| OperatingSystem.IsTvOSVersionAtLeast(11)
#endif
) ? View.SafeAreaInsets.Top : TopLayoutGuide.Length;
CGRect frame = new CGRect(View.Bounds.X, headerTop, View.Bounds.Width, HeaderHeight);
_blurView.Frame = frame;
_header.ViewController.View.Frame = frame;
}
nfloat left;
nfloat top;
nfloat right;
nfloat bottom;
if (OperatingSystem.IsIOSVersionAtLeast(11) || OperatingSystem.IsMacCatalystVersionAtLeast(11)
#if TVOS
|| OperatingSystem.IsTvOSVersionAtLeast(11)
#endif
)
{
left = View.SafeAreaInsets.Left;
top = View.SafeAreaInsets.Top;
right = View.SafeAreaInsets.Right;
bottom = View.SafeAreaInsets.Bottom;
}
else
{
left = 0;
top = TopLayoutGuide.Length;
right = 0;
bottom = BottomLayoutGuide.Length;
}
if (tabThickness > 0)
_additionalSafeArea = new UIEdgeInsets(tabThickness, 0, 0, 0);
else
_additionalSafeArea = UIEdgeInsets.Zero;
if (_didLayoutSubviews)
{
var newInset = new Thickness(left, top, right, bottom);
if (newInset != _lastTabThickness || tabThickness != _lastTabThickness)
{
_lastTabThickness = tabThickness;
_lastInset = new Thickness(left, top, right, bottom);
((IShellSectionController)ShellSection).SendInsetChanged(_lastInset, _lastTabThickness);
}
}
UpdateAdditionalSafeAreaInsets();
}

So someone could read from the SafeAreaInsets property to get the value and then use that for padding if they want to.

@kubaflo
Copy link
Contributor Author

kubaflo commented Feb 8, 2024

I don't know if we can do this.

We intentionally got rid of the padding path. With NET8 we set the additional insets

void LayoutHeader()
{
if (ShellSection == null)
return;
int tabThickness = 0;
if (_header != null)
{
tabThickness = HeaderHeight;
var headerTop = (OperatingSystem.IsIOSVersionAtLeast(11) || OperatingSystem.IsMacCatalystVersionAtLeast(11)
#if TVOS
|| OperatingSystem.IsTvOSVersionAtLeast(11)
#endif
) ? View.SafeAreaInsets.Top : TopLayoutGuide.Length;
CGRect frame = new CGRect(View.Bounds.X, headerTop, View.Bounds.Width, HeaderHeight);
_blurView.Frame = frame;
_header.ViewController.View.Frame = frame;
}
nfloat left;
nfloat top;
nfloat right;
nfloat bottom;
if (OperatingSystem.IsIOSVersionAtLeast(11) || OperatingSystem.IsMacCatalystVersionAtLeast(11)
#if TVOS
|| OperatingSystem.IsTvOSVersionAtLeast(11)
#endif
)
{
left = View.SafeAreaInsets.Left;
top = View.SafeAreaInsets.Top;
right = View.SafeAreaInsets.Right;
bottom = View.SafeAreaInsets.Bottom;
}
else
{
left = 0;
top = TopLayoutGuide.Length;
right = 0;
bottom = BottomLayoutGuide.Length;
}
if (tabThickness > 0)
_additionalSafeArea = new UIEdgeInsets(tabThickness, 0, 0, 0);
else
_additionalSafeArea = UIEdgeInsets.Zero;
if (_didLayoutSubviews)
{
var newInset = new Thickness(left, top, right, bottom);
if (newInset != _lastTabThickness || tabThickness != _lastTabThickness)
{
_lastTabThickness = tabThickness;
_lastInset = new Thickness(left, top, right, bottom);
((IShellSectionController)ShellSection).SendInsetChanged(_lastInset, _lastTabThickness);
}
}
UpdateAdditionalSafeAreaInsets();
}

So someone could read from the SafeAreaInsets property to get the value and then use that for padding if they want to.
@PureWeen
Oh yes, you're right. There is a double spacing added when ios:Page.UseSafeArea="True" Nevertheless, I think it might be a bit confusing for users that setting ios:Page.UseSafeArea="True" is necessary to make shells with top tabs rendered correctly (I wouldn't come up at this initially 😅). Maybe to avoid reporting such issues by users, the padding should be only applied when ios:Page.UseSafeArea is set to false. What do you think about it?

@kubaflo
Copy link
Contributor Author

kubaflo commented Feb 8, 2024

I don't know if we can do this.
We intentionally got rid of the padding path. With NET8 we set the additional insets

void LayoutHeader()
{
if (ShellSection == null)
return;
int tabThickness = 0;
if (_header != null)
{
tabThickness = HeaderHeight;
var headerTop = (OperatingSystem.IsIOSVersionAtLeast(11) || OperatingSystem.IsMacCatalystVersionAtLeast(11)
#if TVOS
|| OperatingSystem.IsTvOSVersionAtLeast(11)
#endif
) ? View.SafeAreaInsets.Top : TopLayoutGuide.Length;
CGRect frame = new CGRect(View.Bounds.X, headerTop, View.Bounds.Width, HeaderHeight);
_blurView.Frame = frame;
_header.ViewController.View.Frame = frame;
}
nfloat left;
nfloat top;
nfloat right;
nfloat bottom;
if (OperatingSystem.IsIOSVersionAtLeast(11) || OperatingSystem.IsMacCatalystVersionAtLeast(11)
#if TVOS
|| OperatingSystem.IsTvOSVersionAtLeast(11)
#endif
)
{
left = View.SafeAreaInsets.Left;
top = View.SafeAreaInsets.Top;
right = View.SafeAreaInsets.Right;
bottom = View.SafeAreaInsets.Bottom;
}
else
{
left = 0;
top = TopLayoutGuide.Length;
right = 0;
bottom = BottomLayoutGuide.Length;
}
if (tabThickness > 0)
_additionalSafeArea = new UIEdgeInsets(tabThickness, 0, 0, 0);
else
_additionalSafeArea = UIEdgeInsets.Zero;
if (_didLayoutSubviews)
{
var newInset = new Thickness(left, top, right, bottom);
if (newInset != _lastTabThickness || tabThickness != _lastTabThickness)
{
_lastTabThickness = tabThickness;
_lastInset = new Thickness(left, top, right, bottom);
((IShellSectionController)ShellSection).SendInsetChanged(_lastInset, _lastTabThickness);
}
}
UpdateAdditionalSafeAreaInsets();
}

So someone could read from the SafeAreaInsets property to get the value and then use that for padding if they want to.
@PureWeen
Oh yes, you're right. There is a double spacing added when ios:Page.UseSafeArea="True" Nevertheless, I think it might be a bit confusing for users that setting ios:Page.UseSafeArea="True" is necessary to make shells with top tabs rendered correctly (I wouldn't come up at this initially 😅). Maybe to avoid reporting such issues by users, the padding should be only applied whenios:Page.UseSafeArea is set to false. What do you think about it?

That would apply only to the top space, so that the content would always be below the tab bars. Another solution would to move tab bars and nav bar up so that they would ignore the safe area if ios:Page.UseSafeArea is false

@PureWeen
Copy link
Member

PureWeen commented Feb 9, 2024

That would apply only to the top space, so that the content would always be below the tab bars. Another solution would to move tab bars and nav bar up so that they would ignore the safe area if ios:Page.UseSafeArea is false

I don't think so, I think because we are using AdditionalSafeAreaInsets the SafeAreaInsets property should be (notch + navbar + AdditionalSafeAreaInsets)

If it's not, then that's a bug with our SafeAreaInsets platform specific.

I think it might be a bit confusing for users

Yea, the entire safe area story is super confusing :-/ we need to just rethink it with new APIs so we're hesitant to make more changes right now.

@kubaflo
Copy link
Contributor Author

kubaflo commented Feb 9, 2024

That would apply only to the top space, so that the content would always be below the tab bars. Another solution would to move tab bars and nav bar up so that they would ignore the safe area if ios:Page.UseSafeArea is false

I don't think so, I think because we are using AdditionalSafeAreaInsets the SafeAreaInsets property should be (notch + navbar + AdditionalSafeAreaInsets)

If it's not, then that's a bug with our SafeAreaInsets platform specific.

I think it might be a bit confusing for users

Yea, the entire safe area story is super confusing :-/ we need to just rethink it with new APIs so we're hesitant to make more changes right now.

Yes, if you're going to rethink the safe area stuff with new APIs, I think it might be better not to change anything and leave it as it is :)

@PureWeen
Copy link
Member

PureWeen commented Feb 9, 2024

Yes, if you're going to rethink the safe area stuff with new APIs, I think it might be better not to change anything and leave it as it is :)

Yea, we're all very grumpy about safe areas right now. That new API IgnoreSafeAreas that's on layouts kind of snuck by early on and we never revisited it. It's led to a ton of very confusing behavior.

Is it alright if we close this PR for now?

@kubaflo
Copy link
Contributor Author

kubaflo commented Feb 9, 2024

Yes, if you're going to rethink the safe area stuff with new APIs, I think it might be better not to change anything and leave it as it is :)

Yea, we're all very grumpy about safe areas right now. That new API IgnoreSafeAreas that's on layouts kind of snuck by early on and we never revisited it. It's led to a ton of very confusing behavior.

Is it alright if we close this PR for now?

Sure, no problem!

@kubaflo kubaflo closed this Feb 9, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Mar 11, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-controls-shell Shell Navigation, Routes, Tabs, Flyout community ✨ Community Contribution platform/iOS 🍎
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Top tab bar on Shell hides content (iOS only)
3 participants