首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Longpress事件触发tap事件

Longpress事件触发tap事件
EN

Stack Overflow用户
提问于 2018-11-11 11:53:26
回答 4查看 1.8K关注 0票数 1

在列表视图中,我有两个事件正在发生,一个是tap事件,另一个是长新闻事件,但是长新闻事件都会触发。在.html文件中:

代码语言:javascript
复制
<ListView class="listViewContainer" [items]="contactList">
  <ng-template let-item="item" let-i="index">
   <StackLayout 
    (loaded)="loaded($event)"
    orientation="horizontal"
    class="preview-info-container"
   >
   </StackLayout>
  </ng-template>
</ListView>

然后是.ts文件

代码语言:javascript
复制
loaded(args) {
const element = args.object;
element.on("loaded, tap, longPress", (args) => {
  // console.log("Event: " + args.eventName + ", sender: " + args.object);
    if(args.eventName === "tap") {
      this.router.navigate(["card/contact/" + this.contact.id]);
    } else {
      this.togglePreviewOptions = !this.togglePreviewOptions;
    }
  });
}

我的问题是,当长时间按压特定字段时,如何防止触发tap事件?

这可能是重复发行的NativeScript tap & longPress together not working,但由于没有明确的答案,我想再次提出它。

编辑更多信息:项目tns版本是

代码语言:javascript
复制
$ tns --version 4.3.0-2018-08-31-12160

全球本地语言版本

代码语言:javascript
复制
nativescript@4.3.0-2018-08-31-12160

模拟器版本:

代码语言:javascript
复制
Iphone 6, iOS 11.3
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-11-11 14:34:11

我无法通过添加两个不同的事件来解决这个问题(tap/longPress)。作为解决方案,我使用以下方法

内部.html

代码语言:javascript
复制
   <StackLayout (touch)="onTouch($event)">
      <Contact-Preview [contact]=contactList[i]></Contact-Preview>
   </StackLayout>

内部.ts

代码语言:javascript
复制
onTouch(args: TouchGestureEventData) {
  if(args.action === "down") {
    this.start = new Date().getMilliseconds();
  }
  if(args.action === "up") {
    this.end = new Date().getMilliseconds();
    const duration = Math.abs(this.start - this.end)
    console.log(duration > 150? "long press": "tap")
  }
}

这样可以防止同时触发tap和longPress事件,从而解决我的问题。

票数 4
EN

Stack Overflow用户

发布于 2020-03-17 14:18:58

我们还遇到了两个事件都是在iOS上触发的问题。基于@GeorgeK的回答,我用服务包装了他的方法。我还确保您可以通过使用项标识符一次按多个项。我还为“取消和移动”操作添加了一个处理程序,以防止在滚动时选择项目:

触摸事件服务:

代码语言:javascript
复制
import { Injectable } from "@angular/core";
import { TouchGestureEventData } from "tns-core-modules/ui/gestures";

@Injectable({
    providedIn: "root"
})
export class TouchEventService {

    static longPressTimeout: number = 500;
    private events: Map<string, number> = new Map<string, number>();
    private startY: Map<string, number> = new Map<string, number>();
    private startX: Map<string, number> = new Map<string, number>();

    constructor() {
    }

    onTouch(args: TouchGestureEventData, id: string, item: any, itemTapCallback?: (item: any) => any, longPressCallback?: (item: any) => any) {
        if (args.action === "down") {
            // When someone starts pressing the element.
            // Create a new timeout that will trigger the long press callback
            // after longPressTimeout.
            this.startX.set(id, args.getX());
            this.startY.set(id, args.getY());
            // @ts-ignore
            this.events.set(id, setTimeout(() => {
                this.clearItem(id);
                longPressCallback(item);
            }, TouchEventService.longPressTimeout));
        } else if (args.action === "up" && this.events.has(id)) {
            // When someone stops pressing the element.
            // If we have an existing event, this means the long press did
            // not trigger yet. Remove the timeout and trigger the tap callback.
            clearTimeout(this.events.get(id));
            this.clearItem(id);
            itemTapCallback(item);
        } else if (args.action === "cancel" && this.events.has(id)) {
            // When someone moves away from the element while pressing.
            // Prevents handlers to be called while scrolling.
            clearTimeout(this.events.get(id));
            this.clearItem(id);
        } else if (args.action === "move" && this.events.has(id)) {
            // When someone moves from the element while pressing.
            // Prevents handlers to be called while scrolling.
            // This is mainly for iOS because they do not trigger cancel
            // when scrolling out of view. But also useful for large items.
            const differenceX = Math.abs(args.getX() - this.startX.get(id));
            const differenceY = Math.abs(args.getY() - this.startY.get(id));
            if (differenceX > 30 || differenceY > 10) {
                clearTimeout(this.events.get(id));
                this.clearItem(id);
            }
        }
    }

    clearItem(id: string) {
        this.events.delete(id);
        this.startX.delete(id);
        this.startY.delete(id);
    }
}

下面是一个如何在组件中实现它的示例: example.component.ts

代码语言:javascript
复制
import { Component } from "@angular/core";
import { TouchEventService } from "./touch-event.service";

@Component({
    selector: "Example",
    templateUrl: "./example.component.html"
})
export class ExampleComponent {
    private _itemTapHandler: (item: any) => any;
    private _longPressHandler: (item: any) => any;

    constructor(public touchEventService: TouchEventService) {
        this._itemTapHandler = this.itemTapHandler();
        this._longPressHandler = this.longPressHandler();
    }

    itemTapHandler(): (item: any) => any {
        return (item) => {
            return this.itemTap(item);
        };
    }

    longPressHandler(): (item: any) => any {
        return (item) => {
            return this.longPress(item);
        };
    }

    itemTap(item: any) {
        // Handle the item tap here.
    }

    longPress(item: any) {
        // Handle the long press here.
    }
}

example.component.html

代码语言:javascript
复制
<StackLayout *ngFor="let item of items" (touch)="touchEventService.onTouch($event, item.id, item, _itemTapHandler, _longPressHandler)">
    <!-- Your item content here, you can use the touch in anything, like list views and scroll views -->
</StackLayout>
票数 3
EN

Stack Overflow用户

发布于 2018-11-11 12:21:54

在模板代码中定义两个事件要容易得多:

代码语言:javascript
复制
<ListView class="listViewContainer" [items]="contactList">
  <ng-template let-item="item" let-i="index">
   <StackLayout 
    (loaded)="loaded($event)"

    (tap)="functionWhenTap(item)" 
    (longPress)="functionWhenLongPress(item)" 

    orientation="horizontal"
    class="preview-info-container"
   >
   </StackLayout>
  </ng-template>
</ListView>

然后,在您的.ts文件中使用以下内容处理它:

代码语言:javascript
复制
  functionWhenTap(item: any) {
    // your things to do when tapped
  }

  functionWhenLongPress(item: any) {
    // your things to do when long pressed
  }

这是一段实际的代码。也应该为你工作。

下面是在我的物理个人设备上测试的工作示例:https://play.nativescript.org/?template=play-ng&id=XgBfFE

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53248470

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档