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

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

void insertCellAtIndex(unsigned int idx, float insertDelayTime);// 这个delaytime只是为了跟其他动画配合,可以独立一个函数
int indexFromPoint(int x, int y);
CCPoint pointFromIndex(int index);

void delayInsertCell();

int m_indexToInsert;		// 延时插入新数据时备份


cpp文件修改:

void CCTableView::insertCellAtIndex(unsigned  int idx, float insertDelayTime)
{
    if (idx == CC_INVALID_INDEX)
    {
        return;
    }

    unsigned int uCountOfItems = m_pDataSource->numberOfCellsInTableView(this);
    if (0 == uCountOfItems || idx > uCountOfItems-1)
    {
        return;
    }

    CCTableViewCell* cell = NULL;
    int newIdx = 0;

    cell = (CCTableViewCell*)m_pCellsUsed->objectWithObjectID(idx);
	m_pIndices->clear();
    if (cell)
    {
        newIdx = m_pCellsUsed->indexOfSortedObject(cell);

		for (int i = 0; i < (int)newIdx; ++i) {
			cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(i);
			m_pIndices->insert(cell->getIdx());
		}

        for (unsigned int i=newIdx; i<m_pCellsUsed->count(); i++)
        {
            cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(i);
			int ni = cell->getIdx()+1;
            this->_setIndexForCell(ni, cell, true);
			m_pIndices->insert(ni);
        }
    }

 //   [m_pIndices shiftIndexesStartingAtIndex:idx by:1];
	if (insertDelayTime > 0) {
		m_indexToInsert = idx;
		CCDelayTime* delay = CCDelayTime::create(0.2f);
		CCCallFunc* call = CCCallFunc::create(this, callfunc_selector(CCTableView::delayInsertCell));
		CCSequence* seq = CCSequence::createWithTwoActions(delay, call);
		this->runAction(seq);
	} else {
		//insert a new cell
		cell = m_pDataSource->tableCellAtIndex(this, idx);
		this->_setIndexForCell(idx, cell, false);
		this->_addCellIfNecessary(cell);

		this->_updateCellPositions();
		this->_updateContentSize();
	}
}

void CCTableView::delayInsertCell()
{
	CCTableViewCell* cell = m_pDataSource->tableCellAtIndex(this, m_indexToInsert);
	this->_setIndexForCell(m_indexToInsert, cell, false);
	this->_addCellIfNecessary(cell);

	this->_updateCellPositions();
	this->_updateContentSize();
}

void CCTableView::removeCellAtIndex(unsigned int idx)
{
    if (idx == CC_INVALID_INDEX)
    {
        return;
    }

    unsigned int uCountOfItems = m_pDataSource->numberOfCellsInTableView(this);
    if (0 == uCountOfItems || idx > uCountOfItems-1)
    {
        return;
    }

    unsigned int newIdx = 0;

    CCTableViewCell* cell = this->cellAtIndex(idx);
    if (!cell)
    {
        return;
    }

    newIdx = m_pCellsUsed->indexOfSortedObject(cell);

    //remove first
    this->_moveCellOutOfSight(cell);

   
    this->_updateCellPositions();
//    [m_pIndices shiftIndexesStartingAtIndex:idx+1 by:-1];

	// 重新修改indices的值
	m_pIndices->clear();
	for (int i = 0; i < (int)newIdx; ++i) {
		cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(i);
		m_pIndices->insert(cell->getIdx());
	}

    for (int i=(int)m_pCellsUsed->count()-1; i >= (int)newIdx; --i)
    {
        cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(i);
		int ni = cell->getIdx()-1;
        this->_setIndexForCell(ni, cell, true);
		m_pIndices->insert(ni);
    }

	// 补充最后一个元素
	if (m_pCellsUsed->count() > 0) {
		cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(m_pCellsUsed->count() - 1);
		int index = cell->getIdx() + 1;
		if (index < (int)m_pDataSource->numberOfCellsInTableView(this)) {
			// 超出显示范围,更新
			this->updateCellAtIndex(index);

			// 更新完毕,重新取最后一个cell
			cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(m_pCellsUsed->count() - 1);
			CCPoint dst = cell->getPosition();
			cell->setPositionX(dst.x + m_vCellsPositions[index] - m_vCellsPositions[index - 1]);
			CCMoveTo* moveTo = CCMoveTo::create(0.2f, dst);
			cell->runAction(moveTo);
		}
	}
}

void CCTableView::_setIndexForCell(unsigned int index, CCTableViewCell *cell, bool animate)
{
	if (!cell) {
		return;
	}
    cell->setAnchorPoint(ccp(0.0f, 0.0f));
	CCPoint pt = this->_offsetFromIndex(index);
	if (animate) {
		CCMoveTo* moveTo = CCMoveTo::create(0.2f, pt);
		cell->runAction(moveTo);
	} else {
		cell->setPosition(pt);
	}

    cell->setIdx(index);
}

int CCTableView::indexFromPoint(int x, int y)
{
	CCPoint offset = this->convertToNodeSpace(ccp(x, y));
	CCPoint of2 = getContentOffset();
	offset.x -= of2.x;
	offset.y -= of2.y;
	int index =  _indexFromOffset(offset);
	CCPoint roffset = _offsetFromIndex(index);
	CCSize size = m_pDataSource->cellSizeForTable(this);
	if (offset.x - roffset.x >= size.width / 2) {
		++index;
	}

	if (index < 0) {
		index = 0;
	}

	int amount = m_pDataSource->numberOfCellsInTableView(this);
	if (index > amount) {
		index = amount;
	}
	return index;
}

CCPoint CCTableView::pointFromIndex(int index)
{
	CCPoint offset = __offsetFromIndex(index);
	CCPoint of2 = getContentOffset();
	offset.x += of2.x;
	offset.y += of2.y;

	CCPoint pt = convertToWorldSpace(offset);
	pt = getParent()->convertToNodeSpace(pt);
	return pt;
}



一些简单的说明:

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

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

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

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值