Nativescript: TextView with dynamic size

Created on 31 Mar 2017  路  12Comments  路  Source: NativeScript/NativeScript

Hi,
a simple question.

I want a TextView that has a dynamic height. With each new line should the height of the Textview increase.

I didn't find any solution. I tried to change the height with the methods "getActualSize().height" and "getMeasuredHeight()", but they give me only the initial value.

  • As Platform I use: iOS
  • tns --version : 2.5.3

Thanks and best regards,
jet-lee-m

ios

Most helpful comment

Hi @jet-lee-m,
To the get the content height of the TextView you could access the native instance of the component and to access contentSize property, which will return the needed value and to setup the new TextView height. For example:

XML

<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo" class="page">

    <Page.actionBar>
        <ActionBar title="My App" icon="" class="action-bar">
        </ActionBar>
    </Page.actionBar>

    <StackLayout class="p-20">
        <Label text="Tap the button" class="h1 text-center"/>
        <TextView id="tvID" loaded="textviewloaded" hint="sample test" updateTextTrigger="textChanged" text="{{textProperty}}" editable="true" />


        <Button text="TAP" tap="onTap" class="btn btn-primary btn-active"/>
        <Label text="{{ message }}" class="h2 text-center" textWrap="true"/>
    </StackLayout>
</Page>

TypeScript

import { EventData, Observable, PropertyChangeData } from 'data/observable';
import { Page } from 'ui/page';
import { HelloWorldModel } from './main-view-model';
import { TextView } from "ui/text-view";
import {isIOS} from "platform"

// Event handler for Page "navigatingTo" event attached in main-page.xml
var page:Page;
var id;
var exist = false;
export function navigatingTo(args: EventData) {

page = <Page>args.object;

    var tmpObservable = new Observable({textProperty:"test"});

    tmpObservable.on(Observable.propertyChangeEvent, (args:PropertyChangeData)=>{
        if(!exist){
            id = setInterval((args)=>{
                if(isIOS){
                    var textview:TextView = <TextView> page.getViewById("tvID");
                    console.log("text height");
                    console.log(textview.height);
                    console.log(textview.getMeasuredHeight());
                    console.log(textview.ios.contentSize.height)
                    textview.height=textview.ios.contentSize.height;
                }

            }, 1000);
            exist=!exist
        }
    })


    page.bindingContext = tmpObservable;
}
export function onTap(){
    console.log("button tap");
    exist=!exist;
    clearInterval(id);
}

Bear on mind that you should clear the time interval in some time for example: on focus lost or button tab event.

All 12 comments

Hi @jet-lee-m,
To the get the content height of the TextView you could access the native instance of the component and to access contentSize property, which will return the needed value and to setup the new TextView height. For example:

XML

<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo" class="page">

    <Page.actionBar>
        <ActionBar title="My App" icon="" class="action-bar">
        </ActionBar>
    </Page.actionBar>

    <StackLayout class="p-20">
        <Label text="Tap the button" class="h1 text-center"/>
        <TextView id="tvID" loaded="textviewloaded" hint="sample test" updateTextTrigger="textChanged" text="{{textProperty}}" editable="true" />


        <Button text="TAP" tap="onTap" class="btn btn-primary btn-active"/>
        <Label text="{{ message }}" class="h2 text-center" textWrap="true"/>
    </StackLayout>
</Page>

TypeScript

import { EventData, Observable, PropertyChangeData } from 'data/observable';
import { Page } from 'ui/page';
import { HelloWorldModel } from './main-view-model';
import { TextView } from "ui/text-view";
import {isIOS} from "platform"

// Event handler for Page "navigatingTo" event attached in main-page.xml
var page:Page;
var id;
var exist = false;
export function navigatingTo(args: EventData) {

page = <Page>args.object;

    var tmpObservable = new Observable({textProperty:"test"});

    tmpObservable.on(Observable.propertyChangeEvent, (args:PropertyChangeData)=>{
        if(!exist){
            id = setInterval((args)=>{
                if(isIOS){
                    var textview:TextView = <TextView> page.getViewById("tvID");
                    console.log("text height");
                    console.log(textview.height);
                    console.log(textview.getMeasuredHeight());
                    console.log(textview.ios.contentSize.height)
                    textview.height=textview.ios.contentSize.height;
                }

            }, 1000);
            exist=!exist
        }
    })


    page.bindingContext = tmpObservable;
}
export function onTap(){
    console.log("button tap");
    exist=!exist;
    clearInterval(id);
}

Bear on mind that you should clear the time interval in some time for example: on focus lost or button tab event.

Hi and thank you for this good idea!

I changed your suggestion a little bit and adjust this for nativescript with angular2.

Template:

<TextView #myText editable="true" hint="Description" [(ngModel)]="text.content" textWrap="true" (ngModelChange)="textChanged()"
    [style.height]="textHeight">
</TextView>

Typescript (Angular2):

@ViewChild("myText") myTextView: ElementRef;
textHeight: number;

textChanged() {
    let textView = <TextView>this.myTextView.nativeElement;
    this.textHeight = textView.ios.contentSize.height;
}

Hi @jet-lee-m,
In our further research, we found that this could be a real issue for iOS.
We will do our best to find, what is causing it and will provide the needed fix.

Bear in mind that the above-given workaround most probably will not work with the upcoming NativeScript version 3.0, which is still under development.

@tsonevn @jet-lee-m

Thanks for your idea. it working well with me :D

@tsonevn Is a dynamic-height text-view on iOS possible in NativeScript yet? It seems to expand on Android, but not iOS. Not sure how intended this behaviour is.

Hi @lukeramsden,
This problem still exists for iOS. To workaround it, you could use the suggestion in my previous comment

Is there a fix for this yet? On iOS, even if you manually change the height of the TextView, the parent does not expand to fit the TextView.

@tsonevn : does this issue resolved..?

Hi @pap5508,
This issue is still under review and at this time I could not commit to the exact time, when the solution will be available. Regarding that, any PR, which provides a fix will be highly appreciated. For more help, you could also review our contribution guidelines.

HI all,
This issue is fixed in the upcoming release.
Meanwhile, you could use the fix with our @next modules:

tns plugin remove tns-core-modules
tns plugin add tns-core-modules@next

Just adding this in case someones wondering:

When using nativescript-iqkeyboardmanager you probably want to add a call to IQKeyboardManager.sharedManager().reloadLayoutIfNeeded(); to the end of your textChanged handler.

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

surdu picture surdu  路  63Comments

atanasovg picture atanasovg  路  50Comments

NickIliev picture NickIliev  路  58Comments

valentinstoychev picture valentinstoychev  路  79Comments

valentinstoychev picture valentinstoychev  路  136Comments