RadListView Swipe Actions Hides Automatically

ios

#1

I am using RadListView with swipe actions as described here. However, i am not sure if this is a feature or a bug, but my swipe actions hide automatically after few seconds (i guess 3). How can i stop that ?


#2

Hi, I’m using those in my app here https://github.com/EddyVerbruggen/nativescript-pluginshowcase (you can install it from the AppStore to compare the behavior).

My guess is something in your app is changing the underlying list, which triggers a redraw of the list, making the actions disappear.


#3

hello @Eddy.
I copied the code from your showcase. The issue is the same. I commented the things i don’t need. Please take a look at this:

 <RadListView row="1" #listView [items]="chatList" class="chat-listview" 
        (itemLoading)="onItemLoading($event)" swipeActions="true" 
        (itemSwipeProgressEnded)="onSwipeCellFinished($event)" 
        (itemSwipeProgressStarted)="onSwipeCellStarted($event)" 
        (itemSwipeProgressChanged)="onCellSwiping($event)">
        <ng-template tkListItemTemplate let-item="item">
            <GridLayout rows="auto" columns="auto, *" class="chat-listview-container" 
                (tap)="onChatTapped($event, item)">
                <WebImage row="0" col="0" [src]="item.thumbnail" stretch="fill" 
                    class="fadeIn img-round img-bordered img-lightgray chat-listview-thumbnail"></WebImage>
                <FlexboxLayout row="0" col="1" class="chat-listview-textcontainer">
                    <Label text="{{ item.name }}" class="chat-listview-heading"></Label>
                    <Label text="{{ item.description }}" class="chat-listview-text"></Label>
                </FlexboxLayout>
            </GridLayout>
        </ng-template>
        <!-- swipe actions template -->
        <GridLayout *tkListItemSwipeTemplate columns="auto, *, auto">
            <GridLayout columns="*, *" col="0" id="left-stack">
              <GridLayout col="0" class="bg-primary" (tap)="onLeftSwipeClick($event)" id="btnName">
                <Label text="name" verticalAlignment="center" horizontalAlignment="center"></Label>
              </GridLayout>
              <GridLayout col="1" class="c-bg-blue" (tap)="onLeftSwipeClick($event)" id="btnPopulation">
                <Label text="population" verticalAlignment="center" horizontalAlignment="center"></Label>
              </GridLayout>
            </GridLayout>
            <GridLayout columns="*" col="2" id="right-stack">
              <GridLayout col="0" class="bg-danger" (tap)="onRightSwipeClick($event)" id="btnDelete">
                <Label text="delete" verticalAlignment="center" horizontalAlignment="center"></Label>
              </GridLayout>
            </GridLayout>
          </GridLayout>
    </RadListView>

Component.ts

    onSwipeCellFinished(args: ListViewEventData) {
        if (args.data.x > 200) {
          console.log("Perform left action");
        } else if (args.data.x < -200) {
          console.log("Perform right action");
        }
        // this.animationApplied = false;
      }
    
      onSwipeCellStarted(args: ListViewEventData) {
        const swipeLimits = args.data.swipeLimits;
        swipeLimits.threshold = args['mainView'].getMeasuredWidth() * 0.2; // 20% of whole width
        swipeLimits.left = args['mainView'].getMeasuredWidth() * 0.65; // 65% of whole width
        swipeLimits.right = args['mainView'].getMeasuredWidth() * 0.35; // 35% of whole width
      }
    
      onCellSwiping(args: ListViewEventData) {
        const swipeView = args['swipeView'];
        this._mainView = args['mainView'];
        this._leftItem = swipeView.getViewById('left-stack');
        this._rightItem = swipeView.getViewById('right-stack');
    
        if (args.data.x > 0) {
          const leftDimensions = View.measureChild(
              <View>this._leftItem.parent,
              this._leftItem,
              layout.makeMeasureSpec(Math.abs(args.data.x), layout.EXACTLY),
              layout.makeMeasureSpec(this._mainView.getMeasuredHeight(), layout.EXACTLY));
          View.layoutChild(<View>this._leftItem.parent, this._leftItem, 0, 0, leftDimensions.measuredWidth, leftDimensions.measuredHeight);
          this.hideOtherSwipeTemplateView("left");
        } else {
          const rightDimensions = View.measureChild(
              <View>this._rightItem.parent,
              this._rightItem,
              layout.makeMeasureSpec(Math.abs(args.data.x), layout.EXACTLY),
              layout.makeMeasureSpec(this._mainView.getMeasuredHeight(), layout.EXACTLY));
    
          View.layoutChild(<View>this._rightItem.parent, this._rightItem, this._mainView.getMeasuredWidth() - rightDimensions.measuredWidth, 0, this._mainView.getMeasuredWidth(), rightDimensions.measuredHeight);
          this.hideOtherSwipeTemplateView("right");
        }
      }
    
      onLeftSwipeClick(args: ListViewEventData) {
        // const city = <City>args.object.bindingContext;
        this._listViewElement.notifySwipeToExecuteFinished();
    
        // if (args.object.id === "btnName") {
        //   prompt({
        //     title: "City name",
        //     defaultText: city.name ? city.name : "",
        //     okButtonText: "Confirm",
        //     cancelButtonText: "Cancel",
        //     cancelable: true
        //   }).then((result: PromptResult) => {
        //     if (result.result) {
        //       city.name = result.text.trim().length === 0 ? undefined : result.text.trim();
        //       this.citiesCollectionRef.doc(city.id).update(
        //           {
        //             name: city.name,
        //             author: this.user ? this.user.email : "Anonymous"
        //           })
        //           .then(() => ad && ad.dismissSoftInput())
        //           .catch(err => console.log(`Update err: ${err}`));
        //     }
        //   });
    
        // } else if (args.object.id === "btnPopulation") {
        //   prompt({
        //     title: "City population",
        //     defaultText: city.population ? "" + city.population : "",
        //     okButtonText: "Confirm",
        //     cancelButtonText: "Cancel",
        //     cancelable: true
        //   }).then((result: PromptResult) => {
        //     if (result.result) {
        //       city.population = +(result.text.trim().length === 0 ? undefined : result.text.trim());
        //       this.citiesCollectionRef.doc(city.id).update(
        //           {
        //             population: city.population,
        //             author: this.user ? this.user.email : "Anonymous"
        //           })
        //           .then(() => ad && ad.dismissSoftInput())
        //           .catch(err => console.log(`Update err: ${err}`));
        //     }
        //   });
        // }
      }
    
      onRightSwipeClick(args) {
        // const city = <City>args.object.bindingContext;
        this._listViewElement.notifySwipeToExecuteFinished();
    
        // this.citiesCollectionRef.doc(city.id).delete()
        //     .then(() => console.log(`Delete city '${city.name}'`))
        //     .catch(err => console.log(`Delete err: ${err}`));
      }
    
      hideOtherSwipeTemplateView(currentSwipeView: string) {
        switch (currentSwipeView) {
          case "left":
            if (this._rightItem.getActualSize().width !== 0) {
              View.layoutChild(<View>this._rightItem.parent, this._rightItem, this._mainView.getMeasuredWidth(), 0, this._mainView.getMeasuredWidth(), 0);
            }
            break;
          case "right":
            if (this._leftItem.getActualSize().width !== 0) {
              View.layoutChild(<View>this._leftItem.parent, this._leftItem, 0, 0, 0, 0);
            }
            break;
          default:
            break;
        }
      }

#4

Do you see the same behavior when you install that app from the store?

I’ve only verified this doesn’t occur on iOS btw, didn’t check Android. Which platforms have you checked?


#5

i am using iOS with 6s and 6s Plus. My app isn’t deployed to store yet…


#7

I’m curious whether or not you also see this behavior when you install this app from the AppStore: https://github.com/EddyVerbruggen/nativescript-pluginshowcase (there’s a link at the top of the readme).


#8

Your plugins showcase just works fine. I upgrade my listview from 3.5.0 to 3.5.7 but still no luck…


#9

I think at this point it’s best to create a playground app (https://play.nativescript.org) reproducing this issue.


#10

oh man…my problem. The list was refreshing after certain time due to my business logic.i commented that code and its fine now.