最近由於功能的需求,寫了一個容器可變的滾動視圖,文字長度也是從網上找的,
這個Demo的效果是這樣的:
在一個指定大小的背景圖上邊,點擊按鈕,出現一條信息,(每次的信息長度不固定),這條信息出現在背景圖的ScrollView上,當信息沒有佔滿ScrollView的大小時,它是不可以滾動的,然後再點擊按鈕,再往這條信息的下方出現一條信息,最後當信息佔滿ScrollView時,會自動向上滾動,ScrollView的大小也會自動根據信息的長度而改變。
下面貼一下源碼:
struct tagNoticeInfo
{
CCLabelTTF* labelNotice;
float fWidth;
};
.h文件
void loadScrollView();
void showNotice(std::string noticeStr);
CCLabelTTF* HorizontalSpacingANDVerticalSpacing(std::string _string, const char *fontName, float fontSize, float horizontalSpacing, float verticalSpacing, float lineWidth);
//CCScrollView
CCLayer* m_layerScrollContain;
CCScrollView* m_scrollViewNotice;
std::vector<tagNoticeInfo> m_vctPriseInfo;
.cpp文件
void CBonusLayer::loadScrollView()
{
m_scrollViewNotice = CCScrollView::create();
m_layerScrollContain = CCLayer::create();//創建一個層,作爲滾動的內容
m_layerScrollContain->setPosition(ccp(0,0));
m_layerScrollContain->setAnchorPoint(ccp(0, 0));
m_layerScrollContain->setContentSize(CCSizeMake(360, 500));
m_scrollViewNotice->setPosition(ccp(10, 25));
m_scrollViewNotice->setAnchorPoint(ccp(0, 0));
m_scrollViewNotice->setContentOffset(ccp(0,500-250));
m_scrollViewNotice->setViewSize(CCSizeMake(360, 500));//設置view的大小
m_scrollViewNotice->setContentSize(CCSizeMake(360, 500));
m_scrollViewNotice->setContainer(m_layerScrollContain);
m_scrollViewNotice->setBounceable(false);
m_scrollViewNotice->setDelegate(this);
m_scrollViewNotice->setTouchPriority(-200);
m_scrollViewNotice->setDirection(kCCScrollViewDirectionVertical);
m_spPriseList -> addChild(m_scrollViewNotice);
}
void CBonusLayer::showNotice(std::string noticeStr)
{
//計算公告的位置
int count = m_vctPriseInfo.size();
float height = 0;
for(unsigned int i = 0; i < count; i++)
{
tagNoticeInfo NoticeInfo = (tagNoticeInfo)m_vctPriseInfo[i];
float width = NoticeInfo.fWidth;
height = height + width/340.0*40+40;//每一個公告的高度
}
tagNoticeInfo NoticeInfo;
NoticeInfo.labelNotice= CCLabelTTF::create(noticeStr.c_str(), "Arial", 32);
NoticeInfo.fWidth = NoticeInfo.labelNotice->getContentSize().width;
NoticeInfo.labelNotice = HorizontalSpacingANDVerticalSpacing(NoticeInfo.labelNotice->getString(), "Arial", 32, 1.5, 1, 340);
float fY = height + NoticeInfo.fWidth/340.0*40+80;
printf("fY is %f\n", fY);
//計算面板是否可以滾動,而且滾動的範圍也要加以限制
if(fY < 500)
{
m_scrollViewNotice->setTouchEnabled(false);
NoticeInfo.labelNotice -> setPosition(ccp(10,500-40 - height));
}
else
{
m_scrollViewNotice->setTouchEnabled(true);
m_layerScrollContain->setContentSize(CCSizeMake(360, fY));
m_layerScrollContain->setPosition(ccp(0,0));
m_scrollViewNotice->setContentSize(CCSizeMake(360, fY));
NoticeInfo.labelNotice -> setPosition(ccp(10,(NoticeInfo.fWidth/340.0*40+40)));
float width = 0;
for(unsigned int i = 0; i < m_vctPriseInfo.size(); i++)
{
tagNoticeInfo NoticeInfo = (tagNoticeInfo)m_vctPriseInfo[i];
width = width + NoticeInfo.fWidth/340.0*40+40;
NoticeInfo.labelNotice -> setPosition(ccp(10,fY-width+NoticeInfo.fWidth/340.0*40));
}
}
NoticeInfo.labelNotice -> setAnchorPoint(ccp(0,0.5f));
m_layerScrollContain -> addChild(NoticeInfo.labelNotice);
m_vctPriseInfo.push_back(NoticeInfo);
}
CCLabelTTF* CBonusLayer::HorizontalSpacingANDVerticalSpacing(std::string _string, const char *fontName, float fontSize, float horizontalSpacing, float verticalSpacing, float lineWidth)
{
CCArray* labelTTF_arr = CCArray::create();
int index = 0;
int index_max = strlen(_string.c_str());
bool is_end = true;
while (is_end) {
if (_string[index] >= 0 && _string[index] <= 127) {
std::string englishStr = _string.substr(index,1).c_str();
const char* englishChar = englishStr.c_str();
labelTTF_arr->addObject(CCLabelTTF::create(englishChar, fontName, fontSize));
index+= 1;
}
else{
std::string chineseStr = _string.substr(index,3).c_str();
const char* chineseChar = chineseStr.c_str();
labelTTF_arr->addObject(CCLabelTTF::create(chineseChar, fontName, fontSize));
index+= 3;
}
if (index>=index_max) {
is_end=false;
}
}
//以上步驟是根據ASCII碼找出中英文字符,並創建成一個CCLabelTTF對象存入labelTTF_arr數組中。
//下面創建的原理是在CCLabelTTF對象上添加子對象CCLabelTTF,以此組合成一句話,以左上角第一個字爲錨點。。
CCLabelTTF* returnTTF = (CCLabelTTF*)labelTTF_arr->objectAtIndex(0);
returnTTF->setColor(ccc3(116, 0, 0));
float nowWidth = returnTTF->getContentSize().width;
CCLabelTTF* dangqiangTTF = returnTTF;
CCLabelTTF* lineBeginTTF = returnTTF;
int arr_count = labelTTF_arr->count();
for (int i=1; i < arr_count; i++) {
CCLabelTTF* beforeTTF = (CCLabelTTF*)labelTTF_arr->objectAtIndex(i);
beforeTTF->setColor(ccc3(116, 0, 0));
beforeTTF->setAnchorPoint(ccp(0, 0.5));
nowWidth+=beforeTTF->getContentSize().width;
if (nowWidth >= lineWidth) {
nowWidth = returnTTF->getContentSize().width;
dangqiangTTF = lineBeginTTF;
beforeTTF->setPosition(ccp(0, -dangqiangTTF->getContentSize().height*0.5-verticalSpacing));
lineBeginTTF = beforeTTF;
}else{
beforeTTF->setPosition(ccp(dangqiangTTF->getContentSize().width+horizontalSpacing, dangqiangTTF->getContentSize().height*0.5));
}
dangqiangTTF->addChild(beforeTTF);
dangqiangTTF = beforeTTF;
}
return returnTTF;
}