[开源] 36行代码实现一个ScrollView/PageView嵌套辅助组件

可以贴段代码展示一下吗?

上面那段代码就是了,注册捕获第一阶段,只需要on最后一个参数设为true

这样只能做到限制父scrollview的方向移动,但是子scrollview的事件就控制不了了,比如我父scrollview限制竖向移动,子scrollview限制横向移动

为啥控制不了子scrollview的事件?

父scroll的事件被子scroll处理,所以可以模拟一个触摸事件,但是子scroll本来就有处理,所以要怎么控制呢?

ok了,忘记stop之前的事件传递了

:6: 2.4.4 有没有人出现滑动父级pageView出现页数滑多了的情况?
比如有 [0, 1, 2, 3, 4] 5个页面,当前在2,手指往右滑动,正常应该是展示1,结果松手变成了0

:2: 解决了,是因为我只有1、3页面上有 ScrollView,而当前展示的2页面上没有 ScrollView 导致的。
解决方法:就是加个判断当前是不是 ScrollView,如果没有,就 return。

    ...
    private onTouchHandle(event: EventTouch) {
        if (event.sham || event.simulate || event.target === this.node) return;
        // 加入下面这句代码
        if (!(event.target.getComponent(cc.ScrollView))) return;
        ...
    }

代码怎么这么好看呢,人比代码更优秀

有个BUG,还要判断是否是内置ScrollView所在节点的事件才模拟新事件

nb plus

请问楼主,我在网页端使用正常,在模拟器和安卓真机上就无效了,请问是咋回事呀

2.4.5版本,我在模拟器试了一下,我这是正常的,你调试一下看看?

我是2.4.6版本,我去看看log

2.4.6版本浏览器正常,模拟器就无效了,然后什么log提示都没有,55555,请问大佬能帮忙看看吗

我刚用2.4.6试了下了,模拟器也是正常的,最起码我这个demo是正常的

多谢大佬,我现在大概知道怎么回事了,浏览器情况下脚本能正常加载走onLoad,但是模拟器跑的时候脚本不加载,现在不太清楚咋回事,我重开编辑器重命名新建文件挂载脚本也不走onLoad,我再看看具体是因为啥哈

3.x 能用不?

mark!!! +1

import * as cc from ‘cc’;

const { ccclass, property } = cc._decorator;

interface EventTouch extends cc.EventTouch {

sham?: boolean

}

@ccclass

export default class ViewGroupNesting extends cc.Component {

private events: EventTouch[] = [];

onLoad() {

    this.node.on(cc.Node.EventType.TOUCH_START, this.onTouchHandle, this, true);

    this.node.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchHandle, this, true);

    this.node.on(cc.Node.EventType.TOUCH_END, this.onTouchHandle, this, true);

    this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchHandle, this, true);

}

private onTouchHandle(event: EventTouch) {

    if (event.sham || event.simulate || event.target === this.node) return;

    const cancelEvent: EventTouch = new cc.EventTouch(event.getTouches(), event.bubbles,cc.EventTouch.prototype.type);

    cancelEvent.type = event.type;

    cancelEvent.touch = event.touch;

    cancelEvent.sham = true;

    // 问:这里为啥不直接dispatchEvent

    // 答:必须让ScrollView把真的event先消耗掉,我们再发射假的才可以,

    // 可以去CCNode.js下找一个_doDispatchEvent函数,里面用到了_cachedArray这么个全局变量,

    // 先发射假的话,真的那个数据就被清空了

    this.events.push(cancelEvent);

}

update() {

    if (this.events.length === 0) return;

    for (let index = 0; index < this.events.length; index++) {

        this.node.dispatchEvent(this.events[index]);

    }

    this.events.length = 0;

}

}

1赞