pageview和 scrollBar并不能同时使用吗 这两天搞的头大
我用的是ts脚本 有大佬告诉我怎么实现吗
根据触摸移动y轴和x轴的位移,哪个先到达滑动触发值,则触发那个方向的滑动
两种方法:
一、自己写触摸滑动,难点是按钮点击事件和滑动事件冲突,需要自己解决
二、修改现有scrollView,加上滑动位移判断,修改scrollView嵌套滑动
附 192版本
`var NUMBER_OF_GATHERED_TOUCHES_FOR_MOVE_SPEED = 5;
var OUT_OF_BOUNDARY_BREAKING_FACTOR = 0.05;
var EPSILON = 1e-4;
var MOVEMENT_FACTOR = 0.7;
var quintEaseOut = function(time) {
time -= 1;
return (time * time * time * time * time + 1);
};
var getTimeInMilliseconds = function() {
var currentTime = new Date();
return currentTime.getMilliseconds();
};
var quintEaseOut = function(time) {
time -= 1;
return (time * time * time * time * time + 1);
};
cc.Class({
extends: cc.ScrollView,
editor: CC_EDITOR && {
menu: 'i18n:MAIN_MENU.component.ui/ScrollView',
help: 'i18n:COMPONENT.help_url.scrollview',
executeInEditMode: false,
},
properties: {
isMoveLocked: true, // 控制滑动是否解锁
isPageView: false, // 控制滑动是否按cell落点
cellWidth: 0, // cell 宽
cellHeight: 0, // cell 高
touchPageStartCallback: null,
touchPageMovedCallback: null,
touchPageEndCallback: null,
touchPageCancelledCallback: null,
controlPosX: 30, // 控制启动x轴滑动临界点
controlPosY: 15, // 控制启动y轴滑动临界点
},
setPageTouchCallback(touchStart, touchMoved, touchEnd, touchCancelled) {
this.touchPageStartCallback = touchStart;
this.touchPageMovedCallback = touchMoved;
this.touchPageEndCallback = touchEnd;
this.touchPageCancelledCallback = touchCancelled;
},
setControlPos(x, y) {
this.controlPosX = x;
this.controlPosY = y;
},
//this is for nested scrollview
_hasNestedViewGroup: function (event, captureListeners) {
// if(event.eventPhase !== cc.Event.CAPTURING_PHASE) return;
if (!this.isMoveLocked) {
return false;
}
// 修改当触摸 scrollView 滑动时,也要检测 是否有嵌套滑动
if (event.eventPhase !== cc.Event.CAPTURING_PHASE && event.target === this.node && !captureListeners) {
captureListeners = [];
event.target._getCapturingTargets(event.type, captureListeners);
}
if(captureListeners) {
//captureListeners are arranged from child to parent
for(var i = 0; i < captureListeners.length; ++i){
var item = captureListeners[i];
if(this.node === item) {
if (event.target.getComponent(cc.ViewGroup) && !event.target.getComponent(cc.ViewGroup).isMoveLocked){
return true;
}
}
if(this.node !== item) {
if(item.getComponent(cc.ViewGroup)) {
if (!item.getComponent(cc.ViewGroup).isMoveLocked) {
return true;
}
}
}
}
}
return false;
},
// 修改原方法, isMoveLocked 控制滑动是否解锁
_handleMoveLogic: function(touch) {
if (this.isMoveLocked)
{
return;
}
var deltaMove = touch.getDelta();
this._processDeltaMove(deltaMove);
},
// 修改原方法, isMoveLocked 控制滑动是否解锁
_handleReleaseLogic: function(touch) {
if (this.isMoveLocked)
{
return;
}
var delta = touch.getDelta();
this._gatherTouchMove(delta);
this._processInertiaScroll();
if (this._scrolling) {
this._scrolling = false;
if (!this._autoScrolling) {
this._dispatchEvent('scroll-ended');
}
}
},
// 修改原方法, 去掉 touchMoveVelocity 与 cc.p(0,0) 的判断
_processInertiaScroll: function () {
var bounceBackStarted = this._startBounceBackIfNeeded();
if (!bounceBackStarted && this.inertia) {
var touchMoveVelocity = this._calculateTouchMoveVelocity();
if (this.brake < 1) {
this._startInertiaScroll(touchMoveVelocity);
}
}
this._onScrollBarTouchEnded();
},
// 修改原方法,达到滑动按照cell落点
_startAutoScroll: function(deltaMove, timeInSecond, attenuated) {
var adjustedDeltaMove = this._flattenVectorByDirection(deltaMove);
this._autoScrolling = true;
this._autoScrollTargetDelta = adjustedDeltaMove;
this._autoScrollAttenuate = attenuated;
this._autoScrollStartPosition = this.getContentPosition();
this._autoScrollTotalTime = timeInSecond;
this._autoScrollAccumulatedTime = 0;
this._autoScrollBraking = false;
this._isScrollEndedWithThresholdEventFired = false;
this._autoScrollBrakingStartPosition = cc.p(0, 0);
// 通过修改 滑动距离和滑动时间,控制 content 最终滑动停止位置
if (this.isPageView && this.vertical && (this.content.y > 0 && this.content.y < this.content.getContentSize().height - this.node.getContentSize().height) ) {
let tempDiff = this.cellHeight;
if(this._autoScrollTargetDelta.y + this.content.y >= this.content.getContentSize().height - this.node.getContentSize().height ||
this._autoScrollTargetDelta.y + this.content.y < 0) {
// 超越 content 滑动范围时,不做操作
} else if (Math.abs(this._autoScrollTargetDelta.y) <= tempDiff) {
// 滑动距离小于等于cell height 时,做回弹处理
let halfDiff = (this.content.y * 1.0) % tempDiff ;
if(halfDiff > tempDiff / 2 )
{
this._autoScrollTargetDelta.y = tempDiff - halfDiff;
}
else
{
this._autoScrollTargetDelta.y = -halfDiff;
}
this._autoScrollTotalTime = 0.2;
} else if ( Math.abs(this._autoScrollTargetDelta.y) > tempDiff ) {
// 滑动距离大于cell height 时,修改滑动距离,以适应 按cell落点
let targetPosY = this.content.y + this._autoScrollTargetDelta.y;
let halfDiff = targetPosY * 1.0 % tempDiff;
if(halfDiff > tempDiff / 2 )
{
this._autoScrollTargetDelta.y = this._autoScrollTargetDelta.y + tempDiff - halfDiff;
}
else
{
this._autoScrollTargetDelta.y = this._autoScrollTargetDelta.y - halfDiff;
}
if (this._autoScrollTotalTime > 0.8) {
this._autoScrollTotalTime = 0.8;
}
}
} else if (this.isPageView && this.horizontal && (this.content.x < 0 && this.content.x > this.node.getContentSize().width - this.content.getContentSize().width)) {
let tempDiff = this.cellWidth;
if(this._autoScrollTargetDelta.x + this.content.x < this.node.getContentSize().width - this.content.getContentSize().width ||
this._autoScrollTargetDelta.x + this.content.x > 0) {
// 超越 content 滑动范围时,不做操作
} else if (Math.abs(this._autoScrollTargetDelta.x) <= tempDiff) {
// 滑动距离小于等于cell width 时,做回弹处理
let halfDiff = Math.abs(this.content.x) * 1.0 % tempDiff ;
if(halfDiff > tempDiff / 2 )
{
this._autoScrollTargetDelta.x = -(tempDiff - halfDiff);
}
else
{
this._autoScrollTargetDelta.x = halfDiff;
}
this._autoScrollTotalTime = 0.2;
} else if ( Math.abs(this._autoScrollTargetDelta.x) > tempDiff ) {
// 滑动距离大于cell width 时,修改滑动距离,以适应 按cell落点
let targetPosX = this.content.x + this._autoScrollTargetDelta.x;
let halfDiff = Math.abs(targetPosX) * 1.0 % tempDiff;
if(halfDiff > tempDiff / 2 )
{
this._autoScrollTargetDelta.x = this._autoScrollTargetDelta.x - tempDiff + halfDiff;
}
else
{
this._autoScrollTargetDelta.x = this._autoScrollTargetDelta.x + halfDiff;
}
}
}
var currentOutOfBoundary = this._getHowMuchOutOfBoundary();
if (!cc.pFuzzyEqual(currentOutOfBoundary, cc.p(0, 0), EPSILON)) {
this._autoScrollCurrentlyOutOfBoundary = true;
var afterOutOfBoundary = this._getHowMuchOutOfBoundary(adjustedDeltaMove);
if (currentOutOfBoundary.x * afterOutOfBoundary.x > 0 ||
currentOutOfBoundary.y * afterOutOfBoundary.y > 0) {
this._autoScrollBraking = true;
}
}
},
_checkMoveLocked(event) {
var touch = event.touch;
if(!touch) return;
if(!this.isMoveLocked) return;
var deltaMove = cc.pSub(touch.getLocation(), touch.getStartLocation());
if (this.vertical && this.content.height >= this.node.height) {
if (Math.abs(deltaMove.y) >= this.controlPosY * cc.view.getScaleY()) {
this.isMoveLocked = false;
}
}
if (this.horizontal && this.content.width >= this.node.width) {
if (Math.abs(deltaMove.x) >= this.controlPosX * cc.view.getScaleX()) {
this.isMoveLocked = false;
}
}
},
// touch event handler
_onTouchBegan: function(event, captureListeners) {
if (!this.enabledInHierarchy) return;
if (this._hasNestedViewGroup(event, captureListeners)) return;
var touch = event.touch;
if (this.content) {
this._handlePressLogic(touch);
if (this.touchPageStartCallback) {
this.touchPageStartCallback(event);
}
}
this._touchMoved = false;
this.isMoveLocked = true;
this._stopPropagationIfTargetIsMe(event);
},
_onTouchMoved: function(event, captureListeners) {
if (!this.enabledInHierarchy) return;
if (this._hasNestedViewGroup(event, captureListeners)) return;
this._checkMoveLocked(event);
var touch = event.touch;
if (this.content) {
if (this.touchPageMovedCallback && !this.isMoveLocked) { // 当isMoveLocked为true时不做移动操作
this.touchPageMovedCallback(event);
} else {
this._handleMoveLogic(touch);
}
}
// Do not prevent touch events in inner nodes
if (!this.cancelInnerEvents) {
return;
}
var deltaMove = cc.pSub(touch.getLocation(), touch.getStartLocation());
// FIXME: touch move delta should be calculated by DPI.
if (cc.pLength(deltaMove) > 7) {
if (!this._touchMoved && event.target !== this.node) {
// Simulate touch cancel for target node
var cancelEvent = new cc.Event.EventTouch(event.getTouches(), event.bubbles);
cancelEvent.type = cc.Node.EventType.TOUCH_CANCEL;
cancelEvent.touch = event.touch;
cancelEvent.simulate = true;
event.target.dispatchEvent(cancelEvent);
this._touchMoved = true;
}
}
this._stopPropagationIfTargetIsMe(event);
},
_onTouchEnded: function(event, captureListeners) {
if (!this.enabledInHierarchy) return;
if (this._hasNestedViewGroup(event, captureListeners)) return;
this._dispatchEvent('touch-up');
var touch = event.touch;
if (this.content) {
if (this.touchPageEndCallback) {
if (this._scrolling || this._autoScrolling) {
this._scrolling = false;
}
this.touchPageEndCallback(event);
} else {
this._handleReleaseLogic(touch);
}
}
if (this._touchMoved) {
event.stopPropagation();
} else {
this._stopPropagationIfTargetIsMe(event);
}
this.isMoveLocked = true;
},
_onTouchCancelled: function(event, captureListeners) {
if (!this.enabledInHierarchy) return;
if (this._hasNestedViewGroup(event, captureListeners)) return;
// Filte touch cancel event send from self
if (!event.simulate) {
var touch = event.touch;
if(this.content){
if (this.touchPageCancelledCallback) {
if (this._scrolling || this._autoScrolling) {
this._scrolling = false;
this._autoScrolling = false;
}
this.touchPageCancelledCallback(event);
} else {
this._handleReleaseLogic(touch);
}
}
}
this._stopPropagationIfTargetIsMe(event);
this.isMoveLocked = true;
},
});
`
// 修改 事件分发函数,原函数cachedArray用函数外局部变量赋值,在嵌套调用时,会把记录状态抹掉,导致错误,改成cachedArray为函数内局部变量,解决该问题(192版本)
cc.Node.prototype.dispatchEvent = function(event) {
let owner = this as any;
event.target = owner;
// Event.CAPTURING_PHASE
let cachedArray = [];
owner._getCapturingTargets(event.type, cachedArray);
// capturing
event.eventPhase = 1;
for (let i = cachedArray.length - 1; i >= 0; --i) {
let target = cachedArray[i];
if (target._isTargetActive(event.type) && target._capturingListeners) {
event.currentTarget = target;
// fire event
target._capturingListeners.invoke(event, cachedArray);
// check if propagation stopped
if ((event as any)._propagationStopped) {
cachedArray.length = 0;
return;
}
}
}
cachedArray.length = 0;
// Event.AT_TARGET
// checks if destroyed in capturing callbacks
if (owner._isTargetActive(event.type)) {
// Event.AT_TARGET
event.eventPhase = 2;
event.currentTarget = owner;
if (owner._capturingListeners) {
owner._capturingListeners.invoke(event);
}
if (!(event as any)._propagationImmediateStopped && owner._bubblingListeners) {
owner._bubblingListeners.invoke(event);
}
}
if (!((event as any)._propagationStopped) && event.bubbles) {
// Event.BUBBLING_PHASE
owner._getBubblingTargets(event.type, cachedArray);
// propagate
event.eventPhase = 3;
for (let i = 0; i < cachedArray.length; ++i) {
let target = cachedArray[i];
if (target._isTargetActive(event.type) && target._bubblingListeners) {
event.currentTarget = target;
// fire event
target._bubblingListeners.invoke(event);
// check if propagation stopped
if ((event as any)._propagationStopped) {
cachedArray.length = 0;
return;
}
}
}
}
cachedArray.length = 0;
};