Search code examples
nativescript-vue

Nativescript Vue Image stretch aspectFill not working


I am working on a Nativescript-vue app, and am having a strange problem with the Image component not sizing correctly.

I am trying to use stretch="aspectFill" to correctly size an image for a component. It works initially when live previewing in the ios simulator, but when you next render the component it reduces size to fit the space rather than aspectFill. My component code is below.

 <StackLayout>
    <Image :src="promo.image" stretch="aspectFill" height="200" />
    <StackLayout class="promocontainer" row="1" padding="0">
      <GridLayout columns="*,*" class="region">
        <Label col="0" :text="promo.region" />
        <Label col="1" :text="'$' + promo.price" textAlignment="right" />
      </GridLayout>
      <Label :text="promo.inclusions_heading" class="heading" />
      <Label :text="promo.heading" padding="10" textWrap="true" class="tagline" />
      <Label :text="promo.introText" padding="10" textWrap="true" class="text" />
    </StackLayout>
  </StackLayout>

When you change the strech option, the live preview in ios show the intended behavior as shown below

enter image description here

When interacting with the app, navigating away from this page and back, or previewing on a physical ios device, the image is show as below, instead of the intended aspect filled image as above.

Unexpected behavior

I am hoping someone has run into this before and might be able to assist with working out a solution.


Solution

  • The component was being added to a ListView, which was causing the rendering issues above. I resolved this by instead wrapping the components in a ScrollView and StackLayout. This solved the stretch rendering issue straight away.

    Original code with stretch bug:

    <ListView for="promo in promos" @itemTap="onPromoTap">
       <v-template>
          <PromoListItem :promo="promo" />
       </v-template>
    </ListView>
    

    Solution:

    <ScrollView>
        <StackLayout>
            <PromoListItem margin="10" v-for="promo in promos" :key="promo.heading" :promo="promo" />
        </StackLayout>
    </ScrollView>
    

    It looks like ListView calculates it's item sizing differently, and is not compatible with Image stretch, at least when there is other content involved.