UI Nodesを試す TableView編


cocos2d-x v3系のTableViewを試したので、メモ。
今回は表示する内容をVectorで持つことにしました。

完成イメージ

下記にお試しコードを記載

HelloWorldScene.h

#include "cocos2d.h"
#include "extensions/cocos-ext.h"

USING_NS_CC;
USING_NS_CC_EXT;

class HelloWorld : public Layer,
                   public TableViewDataSource,
                   public TableViewDelegate {
private:
    std::vector<std::string> _contents;

public:
    static cocos2d::Scene* createScene();
    virtual bool init();

    // TableView Delegate
    virtual Size cellSizeForTable(TableView* table);
    virtual TableViewCell* tableCellAtIndex(TableView* table, ssize_t idx);
    virtual ssize_t numberOfCellsInTableView(TableView* table);
    virtual void tableCellTouched(TableView* table, TableViewCell* cell);

    CREATE_FUNC(HelloWorld);
};

本来であれば、headerファイルでUSING_NS_xxx;を指定するのは辞めたほうがいいですね。

HelloWorldScene.cpp

bool HelloWorld::init()
{
    if (!Layer::init()) {
        return false;
    }

    Size visibleSize = Director::getInstance()->getVisibleSize();

    // Data
    _contents = {
        "つば九郎",
        "つばみ",
        "トルクーヤ",
    };

    // TableView
    TableView* tableView = TableView::create(this, Size(visibleSize.width, visibleSize.height));
    tableView->setDirection(TableView::Direction::VERTICAL);
    tableView->setVerticalFillOrder(TableView::VerticalFillOrder::TOP_DOWN);
    tableView->setAnchorPoint(Vec2::ZERO);
    tableView->setPosition(Vec2::ZERO);
    tableView->setDelegate(this);
    this->addChild(tableView);
    tableView->reloadData();

    return true;
}

//---------------------------------------------------------------
#pragma mark - Table View Delegate
//---------------------------------------------------------------

ssize_t HelloWorld::numberOfCellsInTableView(TableView* table)
{
    return _contents.size();
}

Size HelloWorld::cellSizeForTable(TableView* table)
{
    return Size(table->getContentSize().width, 100);
}

void HelloWorld::tableCellTouched(TableView* table, TableViewCell* cell)
{
    // log("cellがタップされました");
}

TableViewCell* HelloWorld::tableCellAtIndex(TableView* table, ssize_t idx)
{
    TableViewCell* cell = table->dequeueCell();
    cell = new TableViewCell();
    cell->autorelease();

    // セルの背景
    auto bg = Sprite::create();
    bg->setAnchorPoint(Vec2(0, 0));
    bg->setTextureRect(Rect(0, 0, table->getContentSize().width, 99));
    bg->setColor(Color3B(230, 230, 230));
    cell->addChild(bg);

    // テキスト
    auto text = StringUtils::format("%ld : %s", idx, _contents[idx].c_str());
    auto label = Label::createWithSystemFont(text.c_str(), "fonts/Marker Felt.ttf", 30);
    label->setAnchorPoint(Vec2::ZERO);
    label->setPosition(Vec2(50, 30));
    label->setColor(Color3B(100, 100, 100));
    cell->addChild(label);

    return cell;
}


特別なケースでなければ、TableViewCellのwidthはTableViewのwidthに合わせて良いかと思います。

主なTable設定

setDirection : テーブルの方向指定

enum class Direction
{
    NONE = -1,      // 縦横両方向 ( バウンスが効かない ) 
    HORIZONTAL = 0, // 横方向
    VERTICAL,       // 縦方向
    BOTH            // 縦横両方向
};

setVerticalFillOrder : セルの表示順指定

enum class VerticalFillOrder
{
    TOP_DOWN, // 上から下
    BOTTOM_UP // 下から上
};

所感

モリモリなCellを用意するのであれば、TableViewCellのサブクラスを用意したほうがいいですね。
少し動作感がチープですが、実装も簡単なので満足?です。

参考 : http://www.cocos2d-x.org/reference/native-cpp/V3.6/d2/d4b/classcocos2d_1_1extension_1_1_table_view.html