NativeScript / nativescript-angular

Integrating NativeScript with Angular
http://docs.nativescript.org/angular/tutorial/ng-chapter-0
Apache License 2.0
1.21k stars 240 forks source link

[iOS] BottomNavigation with custom TabStrip is "cutting" any scrollable content #2116

Open NickIliev opened 4 years ago

NickIliev commented 4 years ago

@NickIliev commented on Thu Jan 02 2020

Environment

Describe the bug

Using custom tan strip with scrollable content is causing the last portion of the content to be hidden behind the tab strip. Possible related to https://github.com/NativeScript/NativeScript/issues/7471

To Reproduce

Expected behavior

To be able to scroll all scrollable content outside the tabstrip item.

Sample project

https://play.nativescript.org/?template=play-ng&id=xDXBee&v=8&_ga=2.96675223.942765476.1577959082-1966613037.1569573015

Additional context

Probably related to https://github.com/NativeScript/NativeScript/issues/7471

Reported via t.1447435


@NickIliev commented on Mon Jan 06 2020

The solution is to wrap the BottomNavigation in an additional layout. Playground demo here


@NickIliev commented on Wed Jan 08 2020

It seems that the grid-wrapping solution above is not working when we have a page-router-outlet as tab content. For example the issue is present when there is a large scrollable content in one of the page-router-outlets as shown below

    <BottomNavigation #bottomNav
                      (selectedIndexChanged)="activateOutlet($event.newIndex)"
                      (loaded)="onBottomNavLoaded()">
      <TabContentItem><page-router-outlet name="overviewTab"></page-router-outlet></TabContentItem>
      <TabContentItem><page-router-outlet name="paymentTab"></page-router-outlet></TabContentItem>
      <TabContentItem><page-router-outlet name="communityTab"></page-router-outlet></TabContentItem>
      <TabContentItem><page-router-outlet name="feedTab"></page-router-outlet></TabContentItem>
      <TabContentItem><page-router-outlet name="moreTab"></page-router-outlet></TabContentItem>
    </BottomNavigation>

@NickIliev commented on Tue Jan 14 2020

This issue seems closely related to the above behavior


@vakrilov commented on Mon Jan 20 2020

We found that the issue is related to this "simple" rule and is caused by the NSEmptyOutletComponent used in Angular when there is lazy loaded modules. It renders a Frame which is not wrapped in a layout and the result is that it sometimes gets its dimensions wrong.

There is an easy workaround - implement and use a custom version of NSEmptyOutletComponent. The approach is shown in this repo. The custom empty outlet implementation (and usage in the routing module) is in this commit.

vakrilov commented 4 years ago

We are currently considering of adding the WrappedEmptyOutletComponent implementation into the @nativescript/angular package. Any feedback on this proposal will be helpful to make the decision.

We have considered having the additional wrapping layout in the current NSEmptyOutletComponent implementation, but discarded the idea as in many of the default cases you don't actually need it.

flodaniel commented 4 years ago

I just tried to implement this fix with 6.4, however I do not manage to get it working. We use a Bottom Navigation with a Custom Tabstrip, as in your repository. However when navigation into a detail page and back out, the Bottom navigation gets a Whitespace added on top of the tabs.

Component:

<GridLayout rows="*,auto">

    <GridLayout>
        <BottomNavigation #mainNavigation id="nav-bar">
            <TabContentItem>
                <page-router-outlet name="tab0" actionBarVisibility="never"></page-router-outlet>
            </TabContentItem>
            <TabContentItem>
                <page-router-outlet name="tab1" actionBarVisibility="never"></page-router-outlet>
            </TabContentItem>
            <TabContentItem>
                <page-router-outlet name="tab2" actionBarVisibility="never"></page-router-outlet>
            </TabContentItem>
            <TabContentItem>
                <page-router-outlet name="tab3" actionBarVisibility="never"></page-router-outlet>
            </TabContentItem>
            <TabContentItem>
                <page-router-outlet name="tab4" actionBarVisibility="never"></page-router-outlet>
            </TabContentItem>
        </BottomNavigation>
    </GridLayout>

    <!-- Custom TabStrip -->
    <GridLayout row="1" #mainNavigationStrip columns="*, *, *, *, *" class="mainNavigationStrip">
        <car-custom-tabstrip-item col="0" id="tab0" icon="&#xf153;" class="nav-icon" [class.ios]="isIOS()"
         (itemTap)="onTabStripItemTap($event)">
        </car-custom-tabstrip-item>
        <car-custom-tabstrip-item col="1" id="tab1" icon="&#xf375;" class="nav-icon" [class.ios]="isIOS()"
        itemTap)="onTabStripItemTap($event)">
        </car-custom-tabstrip-item>
        <car-custom-tabstrip-item col="2" id="tab2" icon="&#xf100;" class="nav-icon" [class.ios]="isIOS()"
     (itemTap)="onTabStripItemTap($event)">
        </car-custom-tabstrip-item>
        <car-custom-tabstrip-item col="3" id="tab3" icon="&#xf25d;" class="nav-icon" [class.ios]="isIOS()"
          (itemTap)="onTabStripItemTap($event)">
        </car-custom-tabstrip-item>
        <car-custom-tabstrip-item col="4" id="tab4" icon="&#xf345;" class="nav-icon" [class.ios]="isIOS()"
         (itemTap)="onTabStripItemTap($event)">
        </car-custom-tabstrip-item>
    </GridLayout>

</GridLayout>

I tested it on an Iphone 11 Pro Max Simulator.

flodaniel commented 4 years ago

Ok so actually it would work, and would not cut off the page-router-outlet content. But it does it by adding a whitespace as top margin to the BottomNavigation (Custom TabstripItem = Gridlayout).

NickIliev commented 4 years ago

For anyone interested in how to resolve similar case make sure to follow the simple rule

We found that the issue is related to this "simple" rule and is caused by the NSEmptyOutletComponent used in Angular when there is lazy loaded modules. It renders a Frame which is not wrapped in a layout and the result is that it sometimes gets its dimensions wrong.

There is an easy workaround - implement and use a custom version of NSEmptyOutletComponent. The approach is shown in this repo. The custom empty outlet implementation (and usage in the routing module) is in this commit.