cocos2d-x 2.0.4 版本中,CCTableView点击某个cell时,很多情况下都没有响应,这个时候往往列表会移动一下。
看了下CCTableView的源码,是由于判断存在移动则不触发点击事件导致的,因为有的手机屏幕比较敏感,随便按一下都会出现几个移动事件,导致误判的,解决思路:
1.自己写一个类继承CCTableView类
2.增加ccTouchBegan()事件处理,记录点击的位置和时间,精确到毫秒.
3.增加ccTouchMove()事件处理, 记录当前位置
4.继承ccTouchEnd事件,去掉原来的判断中的isTouchMove()判断,增加自己的判断逻辑:
如果时间很短(<150ms),而且移动距离很短(<ccp(10,10)), 则认为没有移动,否则认为有移动。
附上我的源代码:
MyTableView.h:
#ifndef __MYTABLEVIEW_H__ #define __MYTABLEVIEW_H__ #include "cocos2d.h" #include "cocos-ext.h" #include <stdio.h> #include <sys/time.h> #include <time.h> USING_NS_CC; USING_NS_CC_EXT; class MyTableView : public CCTableView { public: bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent); void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent); void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent); static MyTableView* create(CCTableViewDataSource* dataSource, CCSize size); static MyTableView* create(CCTableViewDataSource* dataSource, CCSize size, CCNode *container); protected: CCPoint m_beginPoint; CCPoint m_lastPoint; struct timeval m_beginTime; struct timeval m_endTime; }; #endif
MyTableView.cpp:
#include "MyTableView.h" #include <stdlib.h> MyTableView* MyTableView::create(CCTableViewDataSource* dataSource, CCSize size) { return MyTableView::create(dataSource, size, NULL); } MyTableView* MyTableView::create(CCTableViewDataSource* dataSource, CCSize size, CCNode *container) { MyTableView *table = new MyTableView(); table->initWithViewSize(size, container); table->autorelease(); table->setDataSource(dataSource); table->_updateContentSize(); return table; } bool MyTableView::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) { m_beginPoint = pTouch->getLocation(); ::gettimeofday(&m_beginTime, NULL); CCLog("touch begin"); return CCTableView::ccTouchBegan(pTouch, pEvent); } void MyTableView::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent) { m_lastPoint = pTouch->getLocation(); CCTableView::ccTouchMoved(pTouch, pEvent); } void MyTableView::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent) { CCLog("touch end"); ::gettimeofday(&m_endTime, NULL); if (!this->isVisible()) { return; } /// 判断是否有移动 bool isTouchMove = true; float moveRange = 10; // 移动范围小于10个像素 CCLog("bt:%d,%d", m_beginTime.tv_sec, m_beginTime.tv_usec); CCLog("et:%d,%d", m_endTime.tv_sec, m_endTime.tv_usec); long timediff = m_endTime.tv_sec - m_beginTime.tv_sec; timediff = timediff* 1000 + (m_endTime.tv_usec - m_beginTime.tv_usec)/1000; CCLog("timediff:%ld", timediff); // 触屏时间少于150ms if (timediff < 150) { float dx = m_beginPoint.x - m_lastPoint.x; float dy = m_beginPoint.y - m_lastPoint.y; CCLog("bp:%f,%f", m_beginPoint.x, m_beginPoint.y); CCLog("ep:%f,%f, %f, %f", m_lastPoint.x, m_lastPoint.y, dx, dy); if ((-moveRange < dx && dx < moveRange) && (-moveRange < dy && dy < moveRange)) { isTouchMove = false; } } if (m_pTouches->count() == 1 && !isTouchMove) { CCLog("CCTableView::ccTouchEnded not move"); unsigned int index; CCTableViewCell *cell; CCPoint point; point = this->getContainer()->convertTouchToNodeSpace(pTouch); if (m_eVordering == kCCTableViewFillTopDown) { CCSize cellSize = m_pDataSource->cellSizeForTable(this); point.y -= cellSize.height; } index = this->_indexFromOffset(point); cell = this->_cellWithIndex(index); if (cell) { m_pTableViewDelegate->tableCellTouched(this, cell); } } CCScrollView::ccTouchEnded(pTouch, pEvent); }