nativescript-community / ui-label

Alternative to the built-in NativeScript Label but with better performance and additional features such as HTML rendering and more.
Apache License 2.0
19 stars 7 forks source link

bug: sizing issue inside bottom sheet #12

Open bradmartin opened 2 years ago

bradmartin commented 2 years ago

Make sure to check the demo app(s) for sample usage

Make sure to check the existing issues in this repository

If the demo apps cannot help and there is no issue for your problem, tell us about it

Please, ensure your title is less than 63 characters long and starts with a capital letter.

Which platform(s) does your issue occur on?

Please, provide the following version numbers that your issue occurs with:

 "dependencies": {
    "@angular/animations": "~13.2.0",
    "@angular/common": "~13.2.0",
    "@angular/compiler": "~13.2.0",
    "@angular/core": "~13.2.0",
    "@angular/forms": "~13.2.0",
    "@angular/platform-browser": "~13.2.0",
    "@angular/platform-browser-dynamic": "~13.2.0",
    "@angular/router": "~13.2.0",
    "@bradmartin/nativescript-sentry": "file:../patches/bradmartin-nativescript-sentry",
    "@byram/nativescript-scss": "file:../../xplat/nativescript/scss",
    "@byram/scss": "file:../../libs/scss",
    "@nativescript-community/ui-label": "1.2.8",
    "@nativescript-community/ui-material-bottomsheet": "~7.0.25",
    "@nativescript/angular": "~13.0.0",
    "@nativescript/apple-pay": "~0.1.1",
    "@nativescript/biometrics": "~1.0.1",
    "@nativescript/camera": "~5.0.12",
    "@nativescript/core": "file:../patches/nativescript-core-8.2.5.tgz",
    "@nativescript/firebase-analytics": "^2.2.6",
    "@nativescript/firebase-core": "~2.1.0",
    "@nativescript/firebase-messaging": "~2.1.0",
    "@nativescript/google-pay": "~0.1.2",
    "@nativescript/iqkeyboardmanager": "~2.0.0",
    "@nativescript/secure-storage": "~3.0.0",
    "@nativescript/theme": "~3.0.2",
    "@ngx-translate/core": "~13.0.0",
    "@nstudio/nativescript-checkbox": "~2.0.5",
    "@nstudio/nativescript-exoplayer": "~5.0.9",
    "@nstudio/nativescript-filterable-listpicker": "~3.0.1",
    "@nstudio/nativescript-input-mask": "~0.1.2",
    "@nstudio/nativescript-loading-indicator": "~4.1.2",
    "crypto-js": "~4.1.1",
    "email-validator": "~2.0.4",
    "kinvey-js-sdk": "~6.0.2",
    "kinvey-nativescript-sdk": "file:../patches/kinvey-nativescript-sdk",
    "nativescript-feedback": "~2.0.0",
    "nativescript-ngx-fonticon": "~7.0.0",
    "nativescript-ui-sidedrawer": "~10.0.2",
    "rxjs": "~7.5.0",
    "zone.js": "~0.11.5"
  },

Please, tell us how to recreate the issue in as much detail as possible.

Describe the steps to reproduce it.

Is there any code involved?

<GridLayout rows="*, *, auto" columns="auto, *, auto" class="p-20">
  <Label row="0" col="0" colSpan="3" class="h3" [text]="title" textWrap="true"></Label>
  <GridLayout row="1" colSpan="3" rows="*" columns="*">
    <HTMLLabel
      fontSize="14"
      [html]="label"
      linkColor="#336699"
      linkUnderline="true"
      (linkTap)="onLinkTap($event)"
      textWrap="true"
    ></HTMLLabel>
  </GridLayout>
  <Button row="2" col="0" text="No" (tap)="noTap()" class="-secondary" textTransform="capitalize"></Button>
  <Button row="2" col="2" text="Yes" (tap)="yesTap()" class="-primary" textTransform="capitalize"></Button>
</GridLayout>

The fix is by explicitly putting a height value on the HTMLLabel, ideally it should scale and be visible (since textWrap is true). Simulator Screen Shot - iPhone 13 Pro Max - 2022-08-10 at 12 50 30

When height=300 is on the HTMLLabel the full text of the item is shown, but not ideal since the message in the label can vary in length.

Simulator Screen Shot - iPhone 13 Pro Max - 2022-08-10 at 15 41 40

Works but obviously having the large gap not defined in the layout is a negative.

farfromrefug commented 2 years ago

@bradmartin does it work outside of the bottom sheet ?

bradmartin commented 2 years ago

🥸 totally forgot to check, but I believe so, have it in another section of the app and it is fine. Let me double check.

bradmartin commented 2 years ago

Simulator Screen Shot - iPhone 13 Pro Max - 2022-08-11 at 07 50 25 Yea works fine, toward bottom near the button is HTMLLabel with the url. Pretty standard <stacklayout> as parent on that screen stacking the views.

farfromrefug commented 2 years ago

@bradmartin sorry for the late reply. I ll see what I can do. must be an issue with bottomsheet

bradmartin commented 2 years ago

no worries, was gonna try to look into it later today

davecoffin commented 2 years ago

I'm also having this issue with HTMLLabel in a RadListView. Some of the cells render the height correctly, but as you scroll down many HTMLLabels have much of the content cut off.

bradmartin commented 2 years ago

Just digging in and have some logs and a timeout workaround for my use case for now.

onHtmlLabelLoaded(event) {
    const x = event.object as Label;
    console.log(x.height, x.minHeight, x.textWrap, x.nativeView, x.getActualSize(), x.getMeasuredHeight());
    setTimeout(() => {
      x.requestLayout();
      console.log(x.height, x.minHeight, x.textWrap, x.nativeView, x.getActualSize(), x.getMeasuredHeight());
    }, 100);
  }

before the timeout in the loaded event of the HTMLLabel:

CONSOLE LOG: auto {
"value": 0,
"unit": "px"
} true <UITextView: 0x7f9a55052e00; frame = (0 0; 0 0); text = ''; clipsToBounds = YES; gestureRecognizers = <NSArray: 0x6000023f5560>; layer = <CALayer: 0x600002df3b60>; contentOffset: {0, 0}; contentSize: {0, 0}; adjustedContentInset: {0, 0, 0, 0}> {
"width": 0,
"height": 0
} 0

after the timeout:

CONSOLE LOG: auto {
"value": 0,
"unit": "px"
} true <UITextView: 0x7f9a55052e00; frame = (0 0; 388 17); text = 'Lorem ipsum some really r...'; clipsToBounds = YES; tag = 175; gestureRecognizers = <NSArray: 0x6000023f5560>; layer = <CALayer: 0x600002df3b60>; contentOffset: {0, 0}; contentSize: {388, 17}; adjustedContentInset: {0, 0, 0, 0}> {
"width": 388,
"height": 17
} 51

requestLayout() in the timeout causes it to redraw and it does the textWrap correctly for the long string of text to render. Without the requestLayout() the logs are the same but the UI does not update.

bradmartin commented 2 years ago

Okay scratch all of that... even easier workaround for now (tested on iOS Pro 13 max sim and google pixel 4):

  onHtmlLabelLoaded(event) {
    const x = event.object as Label;
    x.text = this._params.context.label;
  }

instead of

  ngOnInit() {
    Logger.info('ConfirmationDialogComponent.ngOnInit()', this._params.context);
    this.title = this._params.context.title;
    this.label = this._params.context.label;
  }

This is dependent on my layout having rows="*" on the grid wrapping the HTMLLabel, using auto and this does not work.

 <GridLayout row="1" colSpan="2" rows="*" columns="*">
    <HTMLLabel
      fontSize="14"
      [html]="label"
      linkColor="#336699"
      linkUnderline="true"
      (linkTap)="onLinkTap($event)"
      textWrap="true"
      (loaded)="onHtmlLabelLoaded($event)"
      marginBottom="10"
    ></HTMLLabel>
  </GridLayout>
davecoffin commented 2 years ago

@bradmartin I tried your solution but i get this when I try setting the text: https://share.getcloudapp.com/rRuQp9Dm

htmlLabelLoaded(args) {
    this._win.setTimeout(() => {
      args.object.text = this.getPostHtml(this.post.message);
    }, 100)
  }

Any ideas?

bradmartin commented 2 years ago

I'd try dropping the timeout and then maybe calling the requestLayout() and see if something ends up working. Def seems like a timing issue with the layout process for the label inside different parents (bottomsheet, rlv)

farfromrefug commented 2 years ago

@bradmartin i cant reproduce the issue here. Can you manage to reproduce it in a simple repro example not angular? That would help a lot. I am thinking the issue comes from somewhere else

davecoffin commented 2 years ago

@farfromrefug have you tried it in a rad List view? I imagine it's the same problem.

farfromrefug commented 2 years ago

No and I am not sure it is the same issue. Plus RLV is too much of a mess and impossible to debug (the simple way). Tbh I don't trust RLV so I couldnt say if the issue comes from RLV or ui-label. So I prefer to debug this with bottomsheet

bradmartin commented 2 years ago

It could be an angular issue since that's something Dave and I have in common here. If you can't repro it without angular, I'm guessing something with the UI and angular data binding possibly causes, which is why the workarounds I've tried seem to be a "fix" for now.

If you already tried to repro it without angular I won't waste my time 👍🏻 thanks for trying though. I know these issues are odd, luckily I worked around mine with the approach of databinding with the loaded event and not the component init.

farfromrefug commented 2 years ago

@bradmartin I did try but maybe my example was not reproducing the full context of your app. any way if you manage at one point to pinpoint it a bit more I can look at it (except from the angular part :p I really avoid this framework, sorry)