cocos2d-x CCTableView动态插入删除元素bug修正及动画表现

cocos2d-x CCTableView动态的插入删除元素有bug,表现异常。  并且我在使用的时候还想添加动画表现(就像UITableView一样,reloadWithAnimation)。 一开始我以为会很复杂,但是测试后发现需要修改的地方并不是很多。 代码只是满足个人的需求,觉得接口不够漂亮的可以再自行修改。

[cpp]  view plain copy
  1. void insertCellAtIndex(unsigned int idx, float insertDelayTime);// 这个delaytime只是为了跟其他动画配合,可以独立一个函数  
  2. int indexFromPoint(int x, int y);  
  3. CCPoint pointFromIndex(int index);  
  4.   
  5. void delayInsertCell();  
  6.   
  7. int m_indexToInsert;        // 延时插入新数据时备份  


cpp文件修改:

[cpp]  view plain copy
  1. void CCTableView::insertCellAtIndex(unsigned  int idx, float insertDelayTime)  
  2. {  
  3.     if (idx == CC_INVALID_INDEX)  
  4.     {  
  5.         return;  
  6.     }  
  7.   
  8.     unsigned int uCountOfItems = m_pDataSource->numberOfCellsInTableView(this);  
  9.     if (0 == uCountOfItems || idx > uCountOfItems-1)  
  10.     {  
  11.         return;  
  12.     }  
  13.   
  14.     CCTableViewCell* cell = NULL;  
  15.     int newIdx = 0;  
  16.   
  17.     cell = (CCTableViewCell*)m_pCellsUsed->objectWithObjectID(idx);  
  18.     m_pIndices->clear();  
  19.     if (cell)  
  20.     {  
  21.         newIdx = m_pCellsUsed->indexOfSortedObject(cell);  
  22.   
  23.         for (int i = 0; i < (int)newIdx; ++i) {  
  24.             cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(i);  
  25.             m_pIndices->insert(cell->getIdx());  
  26.         }  
  27.   
  28.         for (unsigned int i=newIdx; i<m_pCellsUsed->count(); i++)  
  29.         {  
  30.             cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(i);  
  31.             int ni = cell->getIdx()+1;  
  32.             this->_setIndexForCell(ni, cell, true);  
  33.             m_pIndices->insert(ni);  
  34.         }  
  35.     }  
  36.   
  37.  //   [m_pIndices shiftIndexesStartingAtIndex:idx by:1];  
  38.     if (insertDelayTime > 0) {  
  39.         m_indexToInsert = idx;  
  40.         CCDelayTime* delay = CCDelayTime::create(0.2f);  
  41.         CCCallFunc* call = CCCallFunc::create(this, callfunc_selector(CCTableView::delayInsertCell));  
  42.         CCSequence* seq = CCSequence::createWithTwoActions(delay, call);  
  43.         this->runAction(seq);  
  44.     } else {  
  45.         //insert a new cell  
  46.         cell = m_pDataSource->tableCellAtIndex(this, idx);  
  47.         this->_setIndexForCell(idx, cell, false);  
  48.         this->_addCellIfNecessary(cell);  
  49.   
  50.         this->_updateCellPositions();  
  51.         this->_updateContentSize();  
  52.     }  
  53. }  
  54.   
  55. void CCTableView::delayInsertCell()  
  56. {  
  57.     CCTableViewCell* cell = m_pDataSource->tableCellAtIndex(this, m_indexToInsert);  
  58.     this->_setIndexForCell(m_indexToInsert, cell, false);  
  59.     this->_addCellIfNecessary(cell);  
  60.   
  61.     this->_updateCellPositions();  
  62.     this->_updateContentSize();  
  63. }  
  64.   
  65. void CCTableView::removeCellAtIndex(unsigned int idx)  
  66. {  
  67.     if (idx == CC_INVALID_INDEX)  
  68.     {  
  69.         return;  
  70.     }  
  71.   
  72.     unsigned int uCountOfItems = m_pDataSource->numberOfCellsInTableView(this);  
  73.     if (0 == uCountOfItems || idx > uCountOfItems-1)  
  74.     {  
  75.         return;  
  76.     }  
  77.   
  78.     unsigned int newIdx = 0;  
  79.   
  80.     CCTableViewCell* cell = this->cellAtIndex(idx);  
  81.     if (!cell)  
  82.     {  
  83.         return;  
  84.     }  
  85.   
  86.     newIdx = m_pCellsUsed->indexOfSortedObject(cell);  
  87.   
  88.     //remove first  
  89.     this->_moveCellOutOfSight(cell);  
  90.   
  91.      
  92.     this->_updateCellPositions();  
  93. //    [m_pIndices shiftIndexesStartingAtIndex:idx+1 by:-1];  
  94.   
  95.     // 重新修改indices的值  
  96.     m_pIndices->clear();  
  97.     for (int i = 0; i < (int)newIdx; ++i) {  
  98.         cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(i);  
  99.         m_pIndices->insert(cell->getIdx());  
  100.     }  
  101.   
  102.     for (int i=(int)m_pCellsUsed->count()-1; i >= (int)newIdx; --i)  
  103.     {  
  104.         cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(i);  
  105.         int ni = cell->getIdx()-1;  
  106.         this->_setIndexForCell(ni, cell, true);  
  107.         m_pIndices->insert(ni);  
  108.     }  
  109.   
  110.     // 补充最后一个元素  
  111.     if (m_pCellsUsed->count() > 0) {  
  112.         cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(m_pCellsUsed->count() - 1);  
  113.         int index = cell->getIdx() + 1;  
  114.         if (index < (int)m_pDataSource->numberOfCellsInTableView(this)) {  
  115.             // 超出显示范围,更新  
  116.             this->updateCellAtIndex(index);  
  117.   
  118.             // 更新完毕,重新取最后一个cell  
  119.             cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(m_pCellsUsed->count() - 1);  
  120.             CCPoint dst = cell->getPosition();  
  121.             cell->setPositionX(dst.x + m_vCellsPositions[index] - m_vCellsPositions[index - 1]);  
  122.             CCMoveTo* moveTo = CCMoveTo::create(0.2f, dst);  
  123.             cell->runAction(moveTo);  
  124.         }  
  125.     }  
  126. }  
  127.   
  128. void CCTableView::_setIndexForCell(unsigned int index, CCTableViewCell *cell, bool animate)  
  129. {  
  130.     if (!cell) {  
  131.         return;  
  132.     }  
  133.     cell->setAnchorPoint(ccp(0.0f, 0.0f));  
  134.     CCPoint pt = this->_offsetFromIndex(index);  
  135.     if (animate) {  
  136.         CCMoveTo* moveTo = CCMoveTo::create(0.2f, pt);  
  137.         cell->runAction(moveTo);  
  138.     } else {  
  139.         cell->setPosition(pt);  
  140.     }  
  141.   
  142.     cell->setIdx(index);  
  143. }  
  144.   
  145. int CCTableView::indexFromPoint(int x, int y)  
  146. {  
  147.     CCPoint offset = this->convertToNodeSpace(ccp(x, y));  
  148.     CCPoint of2 = getContentOffset();  
  149.     offset.x -= of2.x;  
  150.     offset.y -= of2.y;  
  151.     int index =  _indexFromOffset(offset);  
  152.     CCPoint roffset = _offsetFromIndex(index);  
  153.     CCSize size = m_pDataSource->cellSizeForTable(this);  
  154.     if (offset.x - roffset.x >= size.width / 2) {  
  155.         ++index;  
  156.     }  
  157.   
  158.     if (index < 0) {  
  159.         index = 0;  
  160.     }  
  161.   
  162.     int amount = m_pDataSource->numberOfCellsInTableView(this);  
  163.     if (index > amount) {  
  164.         index = amount;  
  165.     }  
  166.     return index;  
  167. }  
  168.   
  169. CCPoint CCTableView::pointFromIndex(int index)  
  170. {  
  171.     CCPoint offset = __offsetFromIndex(index);  
  172.     CCPoint of2 = getContentOffset();  
  173.     offset.x += of2.x;  
  174.     offset.y += of2.y;  
  175.   
  176.     CCPoint pt = convertToWorldSpace(offset);  
  177. <span style="white-space:pre">  </span>pt = getParent()->convertToNodeSpace(pt);  
  178.     return pt;  
  179. }  



一些简单的说明:

1、插入删除元素时,由于没有正确的设置m_pIndices导致各种表现异常。 cocos2d-iphone的代码是正确的,注意代码里面注释掉的一句。  但是移植时偷懒没有处理,并且是一直没有人处理。。。。

2、添加动画表现非常简单,就是setPosition的时候使用CCMoveTo的action。插入时为了和外部动画配合(比如一个拖拽的元素)所以加了一个延时动画,否则插入的元素会立即显示出来,表现不是很良好。

3、pointFromIndex  indexFromPoint这两个函数同样是为了导出给外部进行坐标计算的(比如拖拽的元素应该动画移动到什么位置然后消失之类的)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值