0
votes

I have been trying to solve this problem for the past few days and I'm just not finding the solution. I have a Nativescript application that loads documents stored on a webAPI server. These documents are long, html documents. As such, I have wrapped the HtmlView tag with a scrollview (WebView won't work in this case as I need to put some buttons at the bottom of the scroll for the customer to sign the document). This works fine on Android, but on iOS, the scroll view doesn't expand to show the entire content until the user rotates their device. Then it will scroll and view everything just fine.

home.component.ts

import { Component, OnInit } from "@angular/core";
import { DocumentService } from "~/home/service/document.service";
import { IDocument, Document } from "~/home/service/document";
@Component({
    selector: "Home",
    moduleId: module.id,
    templateUrl: "./home.component.html"
})
export class HomeComponent implements OnInit {

    constructor(
        private service: DocumentService,) {
        // Use the component constructor to inject providers.
    }

    private document = new Document();
    private text = '';

    ngOnInit() {
        this.text = `<div>Retrieving Document...</div>`;
    }

    ngAfterViewInit(): void {
        this.service.getById('WEB-0000063',3)
                    .then((data: IDocument) => {
                        if (data) {
                            this.document = data;
                            this.text = `<!DOCTYPE><html><body>${this.document.Body}</body></html>`;
                        }
                    });
    }

}

home.component.html

<GridLayout class="page">
    <GridLayout rows="*" cols="*" height="100%">
        <ScrollView row="0" height="100%">
            <StackLayout height="100%">
                <HtmlView [html]="text"></HtmlView>
            </StackLayout>
        </ScrollView>
    </GridLayout>
</GridLayout>

If I hard-code the data, it works fine, but when it comes back from the server, it has the problem, but only on iOS.

Any help is appreciated.

2
Hello, did you find any solution? I've got the same problem - demetrio812

2 Answers

2
votes

To maintain the component more clean, specially for shared code projects, I wrote this directive:

Directive:

import { AfterViewInit, Directive, ElementRef } from '@angular/core';

@Directive({
  selector: '[appFixHtmlView]',
})
export class FixHtmlViewDirective implements AfterViewInit {
  constructor(private htmlView: ElementRef) {}

  ngAfterViewInit() {
    if (this.htmlView && this.htmlView.nativeElement.ios) {
      setTimeout(() => {
        this.htmlView.nativeElement.requestLayout();
      }, 0);
    }
  }
}

Template:

<GridLayout rows="* auto">
  <ScrollView row="0">
    <GridLayout rows="*">
      <HtmlView appFixHtmlView [html]="myObject.contentHtml"></HtmlView>
    </GridLayout>
  </ScrollView>

  <StackLayout row="1">
  ... more markup
  </StackLayout>
</GridLayout>
1
votes

I've solved it thanks to the help of the community: inject the element with @ViewChild and then call myHtmlView.nativeElement.requestLayout(); inside a setTimeout.

In case (like mine) the element is hidden using *ngIf you will also have to wait until it's visible, like this:

@ViewChild('detail') set detail(content: ElementRef) {
    if (content) {
        setTimeout(() => {
            content.nativeElement.requestLayout();
        });
    }
}