Nativescript - having a scrollView in a GridLayout not working on iOS - nativescript

I'm trying to create a layout that has a button row at the top and then a scrollView beneath that:
<GridLayout columns="*,40,10" rows="10,40,*">
<Label row="1" col="1" text="X" tap="close" />
<ScrollView orientation="vertical" col="0" row="2" colSpan="3">
…
</ScrollView>
</GridLayout>
This works on Android, I get a ScrollView that's 50 from the top and the Label with the «X» in it on top.
On iOS, the ScrollView always is at the top of the view, overlapping the «X»-Label.
Any ideas what I'm doing wrong?
NS 8.x

I suspect the issue is that you have two rows but reference them as 1 and 2 rather than 0 and 1.

Related

Nativescript ScrollView not showing on ios

I have AbsoluteLayout in ScrollView with pager and custom components inside Pager. The code is working on Android, but on iOS is nothing shown. Does anyone have some solution?
<ScrollView>
<AbsoluteLayout>
<Pager row="1" #pager [selectedIndex]="currentPagerIndex" width="100%">
<ns-dashboard-profile height="100" *pagerItem></ns-dashboard-profile>
<ns-dashboard-home *pagerItem></ns-dashboard-home>
<ns-dashboard-devices *pagerItem></ns-dashboard-devices>
</Pager>
<FlexboxLayout class="navigation-wrapper" top="230">
<Label text="Profil" (tap)="goToPage('profile')" class="profile-tab"></Label>
<Label text="Početna" (tap)="goToPage('home')" class="home-tab"></Label>
<Label text="Moji uređaji" (tap)="goToPage('devices')" class="my-device-tab"></Label>
</FlexboxLayout>
</AbsoluteLayout>
ScrollView closing tag is not shown in the code snippet.

iOS buttons become unclickable after making a floating layout

I'm creating a custom action bar and my idea is that the actionbar must be transparent (thats why I can't/don't want to use the native one) and behind the action bar there must be content (an image in this case).
I tried multiple ways and all of them with the same result, the iOS button become unclickable for no reason.
Ok, so I have an AbsoluteLayout inside I have GridLayout fixed on top as the custom actionbar and then a ScrollView with 100% width and height, inside the scrollview there's some content. The problem is as soon as I put a button inside the GridLayout this become unclickable only on iOS because in Android works just fine.
Let me show you my example with some code:
<Page actionBarHidden="true">
<AbsoluteLayout>
<GridLayout rows="50, *" backgroundColor="red" top="0" left="0" height="50" id="bar">
<Button text="click" #tap="goToDetailPage" id="buttondelsous"></Button>
</GridLayout>
<ScrollView backgroundColor="blue" width="100%" height="100%" top="0" id="content">
<WrapLayout>
<StackLayout>
<Label text="this is behind"></Label>
</StackLayout>
</WrapLayout>
</ScrollView>
</AbsoluteLayout>
</Page>
As for the styles forcing the custom actionbar being in front of the scrollview I have:
#bar {
z-index: 5;
width: 100%;
}
#content {
z-index: 2;
}
This looks like this on Android:
Same way on iOS but the button "Click" is not working, like if it was behind something..
Any idea on how to fix this or any other approach to get what I need? Remember behind the action I must be able to place content (like a background image that I don't want to place in the Page tag itself but in another layout)
Thanks!
A wise man once told me that Nativescript stacks elements in the order you list them. Try flipping around the order so the button is listed last in the template. I believe you won't even need the z-index line if you flip the order around.
should look like
<Page actionBarHidden="true">
<AbsoluteLayout>
<ScrollView backgroundColor="blue" width="100%" height="100%" top="0" id="content">
<WrapLayout>
<StackLayout>
<Label text="this is behind"></Label>
</StackLayout>
</WrapLayout>
</ScrollView>
<!-- I'm listed second so I will be on top even though I have row="0" -->
<GridLayout rows="50, *" backgroundColor="red" top="0" left="0" height="50" id="bar">
<Button text="click" #tap="goToDetailPage" id="buttondelsous"/>
</GridLayout>
</AbsoluteLayout>
</Page>

GridLayout in ScrollView - NativeScript

I am new to NativeScript. I have 4 images in my page and I want to achieve this.
Except I want my cover image to be of full-height of the screen. This is the code I'm trying.
<ScrollView>
<StackLayout height="100%" width="100%">
<GridLayout columns="*, *" rows="5*, *, *">
<StackLayout
:row="0"
:col="0"
:colSpan="2"
class="bgImage coverImage"
:style="{backgroundImage:`url('${defaultImg}')`}"
></StackLayout>
<StackLayout
:row="calcRow(idx)"
:col="calcCol(idx)"
:colSpan="idx==0?2:1"
v-for="(item,idx) in event.imgs"
:key="idx"
class="bgImage eventImage"
:style="{backgroundImage:`url('${item}')`}"
></StackLayout>
</GridLayout>
</StackLayout>
</ScrollView>
If I didn't give height="100%" to StackLayout it's not even loading the images. If I do give it then there is no scroll.
Here is the playground link Playground Link
You may use the layoutChanged event of your ScrollView where you may calculate the height of it and use it as height for the first image.
Playground Sample

How to correctly handle nested scroll views in Nativescript/Angular

I'm trying to create in Nativescript(Testing it on Android) a view containing a Donut Chart and an Accordion-like list below it, and enable infinite scrolling, so that when i scroll down the chart will scroll up out of the view, leaving the whole screen available for the list.
The problem is that no matter what i try the accordion-list will either scroll out of the view, leaving the chart on top of it, basically appearing like it's hiding behind the chart, or the elements won't display correctly / at all.
This is how my layout is made so far
Index screen
<ScrollView heiht="100%>
<StackLayout>
<DonutChart [chartDataIterable]="chartData"></DonutChart>
<Accordion [items]="items"></Accordion>
</StackLayout>
</ScrollView>
Donut Chart Component
<GridLayout rows="auto">
<RadPieChart row="0" height="300" allowAnimation="true" (pointSelected)="changeDisplayValue($event)" (pointDeselected)="resetToTotal($event)">
<DonutSeries tkPieSeries seriesName="dataSeries" selectionMode="DataPoint" outerRadiusFactor="0.9" expandRadius="0.4"
outerRadiusFactor="0.7" innerRadiusFactor="0.7" [items]="chartDataObservable" valueProperty="value" legendLabel="type"></DonutSeries>
</RadPieChart>
<StackLayout row="0" horizontalAlignment="center" verticalAlignment="center">
<Label horizontalAlignment="center" [text]="currentType"></Label>
<Label horizontalAlignment="center" [text]="currentTypeAmount"></Label>
</StackLayout>
</GridLayout>
Accordion Component
<ListView [items]="items" height="100%">
<ng-template let-item="item">
<AccordionCell [item]="item"></AccordionCell>
</ng-template>
</ListView>
The GridLayout wrapping the chart is used to add some info at the center of the donut, and the accordion height 100% is set to prevent the list view from taking the height of a single cell.
I suspect that the issue is due to ListView integrating a ScrollView by default, thus prioritizing the scrolling in the ListView and never triggering the scrolling of the outer ScrollView since the content never exceeds the screen size.
Since there hasn't been an answer for a week now i'll share the workaround i came up with.
Instead of using a ScrollView to scroll through my chart and accordion(basically ListView) components, i've moved the Chart and positioned it as the first cell of the ListView, this way both scrolling and cell recycling work well. The only drawback is that a little extra cell management is needed in order to make sure that the chart stays on top, without losing the first entry of the list's data source.
accordion.component.ts
ngOnInit(): void {
this.observableItems = new ObservableArray(this.items);
this.observableItems.unshift({});
}
public templateSelector (item: any, index: number, items: ObservableArray<any>){
if(index === 0)
return "chart";
else if(item.date != items.getItem(index-1).date)
return "date";
else
return "default";
}
accordion.component.html
<RadListView [items]="observableItems" [itemTemplateSelector]="templateSelector" (itemLoading)="itemLoading($event)">
<ng-template tkListItemTemplate let-item="item" let-index="index">
<AccordionCell [item]="item" [index]="index" [itemLoadedEvent]="itemLoadedEvent.asObservable()"></AccordionCell>
</ng-template>
<ng-template tkTemplateKey="date" let-item="item" let-index="index">
<StackLayout>
<Label [text]="item?.date | date: 'dd/MM/yyyy'"></Label>
<AccordionCell [item]="item" [index]="index" [itemLoadedEvent]="itemLoadedEvent.asObservable()"></AccordionCell>
</StackLayout>
</ng-template>
<ng-template tkTemplateKey="chart">
<DonutChart [chartDataIterable]="chartDataIterable (chartSectionSelected)="chartSectionSelectedHandler($event)" (chartSectionDeselected)="chartSectionDeselectedHandler()"></DonutChart>
</ng-template>

How to show RadListView on iOS

I have the following code:
<GridLayout row="7" col="0" colSpan="3" rows="*" cols="*">
<RadListView [items]="sourcesOptions" height="100%">
<ng-template tkListItemTemplate let-item="item">
<StackLayout orientation="horizontal">
<Switch [checked]="true" class="switch"></Switch>
<Label [text]="item.label" textWrap="true" marginTop="15"></Label>
</StackLayout>
</ng-template>
<ListViewGridLayout tkListViewLayout itemHeight="200" scrollDirection="Vertical" spanCount="2"></ListViewGridLayout>
</RadListView>
</GridLayout>
It is working on Android, but on iOS it isn't showing anything.
Note
I don't know if this can be related to the issue, but I get the items from a rest service.
Any help is appreciated!!
The problem was with the height when the items are async, in that case I needed to set the height manually to the parent layout of the RadListView component (The GridLayout in my case).
It didn't work if I set a height with percentage (100%), it had to be a fixed number, it was very inconvenient because the number of items are not always the same, so I created a function to set the height according with number of items received.
This is the code that fixed the issue:
<GridLayout row="7" col="0" colSpan="3" rows="*" cols="*" [height]="setHeight()">
<RadListView [items]="sourcesOptions">
<ng-template tkListItemTemplate let-item="item">
<StackLayout orientation="horizontal">
<Switch [checked]="true" class="switch"></Switch>
<Label [text]="item.label" textWrap="true" marginTop="15"></Label>
</StackLayout>
</ng-template>
<ListViewGridLayout tkListViewLayout itemHeight="70" scrollDirection="Vertical" spanCount="2"></ListViewGridLayout>
</RadListView>
</GridLayout>
Try a height value on the RLV component like height="100%" so it fills the parent. iOS doesn't do auto layouts the same android does, that's why you run into this :)
You haven't provided a rows or columns definition for your GridLayout. The RadListView will likely show up if you do:
<GridLayout row="7" col="0" colSpan="3" rows="*" columns="*">

Resources