ListView not addapting on iOS


#1

My Listview works perfectly on Android.
But when i move the project to iOS. the ListView gets completely bugged. Like i will show down below:


The List should expande and show several StackLayouts. Instead its like if all the StackLayouts became 1 and stayed on top of the page.
And there’s just an empty space in all that middle of the screen.

My Html code:

<GridLayout rows="*, auto">
  <StackLayout row="0">
    <ActionBar fontSize="30" title="Movimentos" color="white">
      <NavigationButton text="" android.systemIcon="ic_menu_back" (tap)="onNavBtnTap()" [nsRouterLink]="['/main']" pageTransition="slideRight"></NavigationButton>
      <ActionItem (tap)="onEdit()" icon="res://ic_today_white" ios.position="right" visibility="{{ isEditing ? 'collapse' : 'visible' }}"
        [nsRouterLink]="['/main']" pageTransition="fade"></ActionItem>
    </ActionBar>
    <ListView [items]="everything" (loadMoreItems)="loadMoreItems()" flexGrow="1">
      <ng-template let-item="item">
        <StackLayout (tap)="details(item.id,item.idDocumento)" marginTop="20" marginLeft="20" marginRight="20" marginBottom="10"
          backgroundColor="white" [nsRouterLink]="['/main']" pageTransition="slide" borderRadius="5%">
          <GridLayout rows="auto auto auto" columns="* 75">
            <Label class="labelTransactionType" text="{{item.idDocumento}}" textWrap="true" row="0" col="0" marginTop="10"></Label>
            <Label class="labelTransactionValue" text="{{item.value}}" textWrap="true" row="1" col="0"></Label>
            <Label class="transactionsButtons" text=">" row="1" col="1" marginTop="-5"></Label>
            <Label class="labelTransactionData" text="{{item.date}}" textWrap="true" row="2" col="0" marginBottom="10"></Label>
          </GridLayout>
        </StackLayout>
      </ng-template>
      </ListView>
  </StackLayout>
  <BottomBar row="1" [items]="items" [hide]="hidden" [titleState]="titleState" (loaded)="tabLoaded($event)" (tabSelected)="tabSelected($event)"
    [inactiveColor]="inactiveColor" [accentColor]="accentColor" colored="true"></BottomBar>
</GridLayout>

My component.ts code:

import { Page } from "ui/page";
import { Component, OnInit } from "@angular/core";
import { registerElement } from 'nativescript-angular';
import { BottomBar, BottomBarItem, TITLE_STATE, SelectedIndexChangedEventData, Notification } from 'nativescript-bottombar';
import { NavigationButton } from "ui/action-bar";
import { User } from "../../shared/model/user/user";
import { UserService } from "../../shared/model/user/user.service";
import { MovementService } from "../../shared/model/movement/movement.service";
import { Router, NavigationExtras } from "@angular/router";
import * as colorModule from "tns-core-modules/color";
import { ActivatedRoute } from "@angular/router";
import * as platformModule from "tns-core-modules/platform";
import { screen } from "tns-core-modules/platform/platform"
import * as absoluteLayoutModule from "tns-core-modules/ui/layouts/absolute-layout";
import { EventData, Observable } from "data/observable";
import { setTimeout } from "timer";
import { ScrollEventData } from "ui/scroll-view";
var applicationSettings = require("application-settings");


@Component({
  selector: "transactions",
  providers: [UserService, MovementService],
  templateUrl: "pages/transactions/transactions.html",
  styleUrls: ["pages/transactions/transactions-common.css", "pages/transactions/transactions.css"]
})
export class TransactionsComponent implements OnInit {
  public hidden: boolean;
  public titleState: TITLE_STATE;
  public _bar: BottomBar;
  public inactiveColor: string;
  public accentColor: string;
  public user: User;
  public screenHeight: number;
  public screenWidth: number;
  public test: string;
  public id: string[];
  public date: string[];
  public idDocumento: string[];
  public value: number[];
  public everything: any[] = new Array();
  public monthNames = ["Janeiro ", "Fevereiro", "Março", "Abril", "Maio", "Junho",
    "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"
  ];
  public status = "not scrolling";
  public idDetailedMovement: string;
  public price: string;
  public quantity: string;
  public what: string;
  public counter: number = 0;
  public counterOriginalValue: number = 0;



  constructor(private router: Router, private page: Page, private route: ActivatedRoute, private userService: UserService, private movementService: MovementService) {
    this.route.queryParams.subscribe(params => {
      this.user = JSON.parse(params["user"]);
    })
  }

  public items: Array<BottomBarItem> = [
    new BottomBarItem(0, "Início", "ic_home", "white"),
    new BottomBarItem(1, "Transações", "ic_assignment", "white"),
    new BottomBarItem(2, "Pagar", "ic_add_a_photo", "white"),
    new BottomBarItem(3, "Definições", "ic_settings", "white")
];

  tabLoaded(event) {
    this._bar = <BottomBar>event.object;
    this.hidden = false;
    this.titleState = TITLE_STATE.ALWAYS_SHOW;
    var Color = colorModule.Color;
    var color = new Color("#8e8e93");
    this.inactiveColor = color.hex;
    this.accentColor = "black";
    //this._bar.selectItem(3);
    this._bar.selectItem(1);
  }

  ngOnInit() {

    this.page.actionBarHidden = false;
    this.page.backgroundImage = "res://bitmap";

    this.showTransactions("1");
  }

  showTransactions(pageNumber) {
    let navigationExtras: NavigationExtras = {
      queryParams: {
        "user": JSON.stringify({
          "name": this.user.name,
          "nif": this.user.nif,
          "password": this.user.password
        })
      }
    };

    //MovementPage direct to API
    this.movementService.movementPageAPI(applicationSettings.getString("user.token", "default"), pageNumber)
      .subscribe(res => {
        this.counterOriginalValue++;
        if (res._body.length == 0 && pageNumber == 1) {
          alert("Este utente não tem movimentos!");
          this.router.navigate(["/homePage"], navigationExtras);
        } else {
          if (res._body.length == 1) {
            var date = res._body[0].Data.toString();
            var arr = new Array();
            arr = date.split("-");
            arr[1] = arr[1].substring(1);
            var auxArr = new Array();
            auxArr = arr[2].split("T");

            res._body[0].Valor = this.changeValue(res._body[0].TipoDoc, res._body[0].Valor);
            res._body[0].TipoDoc = this.changeLanguage(res._body[0].TipoDoc);


            this.everything.push({
              id: (res._body[0].Id).toString(),
              date: ("Data: " + auxArr[0] + " de " + this.monthNames[arr[1] - 1] + " de " + arr[0]),
              idDocumento: (res._body[0].TipoDoc).toString(),
              value: (res._body[0].Valor).toString()
            });
          } else {
            if (res._body.length == 10) {
              this.counter++;
            }
            for (var i = 0; i < res._body.length; i++) {

              var date = res._body[i].Data.toString();
              var arr = new Array();
              arr = date.split("-");
              arr[1] = arr[1].substring(1);
              var auxArr = new Array();
              auxArr = arr[2].split("T");

              res._body[i].Valor = this.changeValue(res._body[i].TipoDoc, res._body[i].Valor);
              res._body[i].TipoDoc = this.changeLanguage(res._body[i].TipoDoc);


              this.everything.push({
                id: (res._body[i].Id).toString(),
                date: ("Data: " + auxArr[0] + " de " + this.monthNames[arr[1] - 1] + " de " + arr[0]),
                idDocumento: (res._body[i].TipoDoc).toString(),
                value: (res._body[i].Valor).toString()
              });
            }
            this.router.navigate(["/transactions"], navigationExtras);
          }
        }
      },
      (error) => alert("Sem ligação de dados ativa. Verifique as ligações de dados móveis ou Wi-fi e tente novamente")
      );

  }


  changeLanguage(string) {
    if (string == "Pagamento") {
      return (string = "Pagamento");
    }
    if (string == "Carregamento") {
      return (string = "Carregamento");
    }
    if (string == "Estorno") {
      return (string = "Estorno");
    }
  }

  changeValue(string, num) {
    var decimalcases = this.decimalPlaces(num);
    if (Number.isInteger(num)) {
      num = num + ".00";
    } else {
      var number = this.decimalPlaces(num);
      if (number == 1) {
        num = num + "0";
      } else {
      }
    }
    if (string == "Pagamento") {
      return (num = "- €" + num);
    }
    if (string == "Carregamento") {
      return (num = "+ €" + num);
    }
    if (string == "Estorno") {
      return (num = "+ €" + num);
    }
  }

  decimalPlaces(num) {
    var match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
    if (!match) { return 0; }
    return Math.max(
      0,
      // Number of digits right of decimal point.
      (match[1] ? match[1].length : 0)
      // Adjust for scientific notation.
      - (match[2] ? +match[2] : 0));
  }

  tabSelected(args: SelectedIndexChangedEventData) {
    switch (args.newIndex) {
        case 0: {
            let navigationExtras: NavigationExtras = {
                queryParams: {
                    "user": JSON.stringify({
                        "name": this.user.name,
                        "nif": this.user.nif,
                        "password": this.user.password
                    })
                }
            };
            this.router.navigate(["/homePage"], navigationExtras);
            break;
        }
        case 1: {
            let navigationExtras: NavigationExtras = {
                queryParams: {
                    "user": JSON.stringify({
                        "name": this.user.name,
                        "nif": this.user.nif,
                        "password": this.user.password
                    })
                }
            };
            this.router.navigate(["/transactions"], navigationExtras);
            break;
        }
        case 2: {
            let navigationExtras: NavigationExtras = {
                queryParams: {
                    "user": JSON.stringify({
                        "name": this.user.name,
                        "nif": this.user.nif,
                        "password": this.user.password
                    })
                }
            };
            this.router.navigate(["/payment"], navigationExtras);
            break;
        }
        case 3: {
            let navigationExtras: NavigationExtras = {
                queryParams: {
                    "user": JSON.stringify({
                        "name": this.user.name,
                        "nif": this.user.nif,
                        "password": this.user.password
                    })
                }
            };
            this.router.navigate(["/userSettings"], navigationExtras);
            break;
        }
    }
}

  details(string1, string2) {
    let navigationExtras: NavigationExtras = {
      queryParams: {
        "user": JSON.stringify({
          "name": this.user.name,
          "nif": this.user.nif,
          "password": this.user.password
        }),
        "movementID": string1,
        "type": string2,
      }
    };

    if (string2 == "Pagamento") {
      this.router.navigate(["/paymentDetails"], navigationExtras);
    }

    if (string2 == "Estorno") {
      this.router.navigate(["/refundDetails"], navigationExtras);
    }

    if (string2 == "Carregamento") {
      this.router.navigate(["/bankTransferDetails"], navigationExtras);
    }
  }

  onNavBtnTap() {
    let navigationExtras: NavigationExtras = {
      queryParams: {
        "user": JSON.stringify({
          "name": this.user.name,
          "nif": this.user.nif,
          "password": this.user.password
        })
      }
    };
    this.router.navigate(["/homePage"], navigationExtras);
  }

  onEdit() {
    let navigationExtras: NavigationExtras = {
      queryParams: {
        "user": JSON.stringify({
          "name": this.user.name,
          "nif": this.user.nif,
          "password": this.user.password
        })
      }
    };
    this.router.navigate(["/dateTransaction"], navigationExtras);
  }


  public onScroll(args: ScrollEventData) {
    this.status = "scrolling";

    //ao dar scroll movements by Page 2,3,4,5,...
    setTimeout(() => {
      this.status = "not scrolling";
    }, 300);

    console.log("scrollX: " + args.scrollX);
    console.log("scrollY: " + args.scrollY);

    if (args.scrollY == 929) {
      console.log("Want to see more movements");
    }
  }

  loadMoreItems() {
    if (this.counter == this.counterOriginalValue) {
      this.showTransactions((this.counter + 1));
    }
  }

}

On Android the code is the same and i dont have to tecnically set a height for the ListView.
How do i get for the ListView to expand properly on iOS? It should of expand.

Tecnically every 1 on 10 times it expands. the other 9 it doesn’t.

If anyone could give a hino i woulda appreciate. Thanks.


#2

If i set a height on the ListView on iOS it works. But it doesn’t make sense to set a height. It should adjust…
On Android it worked nicely.