**************************************************************************
Time:2015-01-09
Sharing_li
Reprint Source: http://blog.csdn.net/sharing_li/article/details/42298317
***************************************************************************
People who have played "happy to eliminate music" this game should know that there is such a design, such as:
We can slide the interface left and right, you can also swipe up and down the interface, the left and right sliding can not slide up and down, sliding up and down can not swipe left and right. This effect can be combined with tableview and ScrollView, that is, first get a scrollview, and then put 2 TableView as content into this scrollview, this UI design is also used in the "Happy Consumer Music" in its friend letter , just one more tableview.
Next, the code will be explained, the COCOS2DX version is 3.2, first show the implementation of the following:
After reading, look at the text, define a class: Combineview
Header file: CombineView.h
#ifndef __combine_view_h__#define __combine_view_h__#include "cocos2d.h" #include "extensions/cocos-ext.h" Using_ns_ CC; Using_ns_cc_ext;enum table{table_left = 0,table_center,table_right};class combineview:public Layer, Tableviewdatasource,tableviewdelegate{public:combineview (); ~combineview (); virtual bool init (); Static cocos2d:: Scene * Create (); virtual Size tablecellsizeforindex (TableView *table, ssize_t idx); Virtual tableviewcell* Tablecellatindex (TableView *table, ssize_t idx); virtual ssize_t Numberofcellsintableview (TableView *table); virtual void tablecelltouched (tableview* table, tableviewcell* cell); virtual void Scrollviewdidscroll (scrollview* view); virtual void Scrollviewdidzoom (scrollview* view);p ublic:void SetTouch (bool istouched);//adjustment to ScrollView void Adjustscrollview (float offset);p Rivate:scrollview * M_scrollview; TableView * m_lefttable; TableView * m_centertable; TableView * M_righttable;//scrollview The number of pages currently displayed int m_curpage;//The first touch point Vec2 m_firstpoint;//scrollview offset Vec2 m_offset;// JudgeFirst sliding direction bool M_horizontal;bool m_vertical;//view size of m_viewsize;}; #endif//!__combine_view_h__
Take a look at the CPP file implementation, here the main code to explain, want complete code and resources, please click on the end of the article download (0 download points).
We write code to get into the habit of initializing member variables, which avoids some unexpected mistakes. Remember to release the unused resources as well.
Combineview::combineview () {M_scrollview = Null;m_lefttable = null;m_centertable = null;m_righttable = NULL;m_curPage = 0 ; m_firstpoint = VEC2 (0,0); m_offset = VEC2 (0,0); m_vertical = False;m_horizontal = False;m_viewsize = Size (0,0);}
As shown, we're going to get a scrollview, this guy, with triplets for 5 months, three TableView, respectively. In order to distinguish the three sons (hey, how do you know that all men are not women), we have to give them names, because they have to share a function that is tablecellatindex, if not named, how to know who is the second old three, such as the enumeration class defined in the header file.
M_scrollview = Scrollview::create (); m_scrollview->setviewsize (m_viewsize); M_scrollview->setcontentoffset ( Point::zero); M_scrollview->setdelegate (this); M_scrollview->setdirection (ScrollView::D irection:: horizontal); M_scrollview->setanchorpoint (Point::zero); m_scrollview->setposition (Vec2::ZERO); m_ Scrollview->settouchenabled (false);//Because we don't need scrollView touch because it's too bad ~pview->addchild (M_scrollview);//Add Content Auto Pcontainer = Layer::create ();p container->setcontentsize (Size (M_viewsize.width * 3,m_viewsize.height)); Pcontainer->setanchorpoint (Point::zero);p container->setposition (Vec2::zero);m_scrollView-> Setcontainer (Pcontainer);//Add Tabelviewauto containersize = Pcontainer->getcontentsize (); m_leftTable = TableView: : Create (this, viewsize); M_lefttable->settag (Table_left); m_lefttable->ignoreanchorpointforposition (false); M_lefttable->setanchorpoint (VEC2 (0.5,0.5)); M_lefttable->setposition (VEC2, CONTAINERSIZE.HEIGHT/2)); M_lefttabLe->setdirection (ScrollView::D irection::vertical); M_lefttable->setdelegate (this);m_lefttable-> Setverticalfillorder (Tableview::verticalfillorder::top_down), M_lefttable->reloaddata ();p container-> AddChild (m_lefttable); m_centertable = Tableview::create (this, viewsize); M_centertable->settag (table_center); m_ Centertable->ignoreanchorpointforposition (false); M_centertable->setanchorpoint (VEC2 (0.5,0.5)); m_ Centertable->setposition (VEC2 (CONTAINERSIZE.WIDTH/2,CONTAINERSIZE.HEIGHT/2)); m_centertable->setdirection (ScrollView::D irection::vertical); m_centertable->setdelegate (this); M_centertable->setverticalfillorder ( Tableview::verticalfillorder::top_down); M_centertable->reloaddata ();p container->addchild (m_centerTable); M_righttable = Tableview::create (this, viewsize); M_righttable->settag (table_right);m_righttable-> Ignoreanchorpointforposition (false); M_righttable->setanchorpoint (VEC2 (0.5,0.5));m_righttable-> SetPosition (VEC2 (CONTAINERSIZE.WIDTH/6* 5,CONTAINERSIZE.HEIGHT/2)); M_righttable->setdirection (ScrollView::D irection::vertical);m_righttable-> Setdelegate (this); M_righttable->setverticalfillorder (Tableview::verticalfillorder::top_down); m_rightTable- >reloaddata ();p container->addchild (m_righttable);
Then let's take a look at the implementation of the touch function, first of all Touchbegan:
Auto Listenert = Eventlistenertouchonebyone::create (); Listenert->ontouchbegan = [=] (Touch * touch,event * pEvent) {m_ Firstpoint = Touch->getlocation (); m_offset = M_scrollview->getcontentoffset (); if (!m_scrollview-> Getboundingbox (). Containspoint (M_firstpoint)) {return false;} return true;};
Simple and clear (...) and then look at touchmoved:
listenert->ontouchmoved = [=] (Touch * touch,event * pevent) {Auto Movepoint = touch->getlocation (); Auto distance = mo Vepoint.x-m_firstpoint.x;if ((Distance > 0 && this->m_curpage = 0) | | (Distance < 0 && This->m_curpage = = 2)) {return;} Limit slide direction to avoid scorll and table sliding if (fabs (MOVEPOINT.Y-M_FIRSTPOINT.Y)/fabs (distance) > 0.7 | | m_vertical) {if (!m_ Horizontal) {m_vertical = true;} return;} else//Level {if (!m_vertical) {m_horizontal = true;}} if (m_horizontal) {This->settouch (false);} M_scrollview->setcontentoffset (VEC2 (distance + m_offset.x,0);};
This piece of code means: If you swipe vertically first, then set m_vertical to True so you can't slide horizontally, and if you swipe horizontally first, set M_horizontal to True, calling function SetTouch, Sing a lullaby to the three children and tableview them to sleep. And then look at touchended:
listenert->ontouchended = [=] (Touch * touch,event * pevent) {Auto EndPoint = touch->getlocation (); Auto distance = end point.x-m_firstpoint.x;//optimized sliding effect BOOL flag = False;if (FABSF (distance) <) {flag = true;if (Distance < 0) {M_curpage --;} else if (Distance > 0) {m_curpage++;}} Limit the slide direction to avoid scroll and table sliding if (m_vertical) {m_vertical = FALSE;IF (flag) {if (distance > 0) {m_curpage--;} else if (distance < 0) {m_curpage++;}} return;} Else{this->settouch (TRUE);} This->adjustscrollview (distance); m_horizontal = false;};
This piece of code means: if (FABSF (distance) < 60) This if statement is the optimization of the sliding effect, if the slide is very small distance, then ignore this slide, the view is still the same, as follows:
This should be at a glance, the next code is to determine whether the first vertical or horizontal sliding, if the first vertical, then directly return,return to restore the value of m_curpage. If it is the first level, you have to wake up three sleeping children. Then there is the adjustment to the ScrollView final display interface:
void Combineview::adjustscrollview (float offset) {if (offset < 0) {m_curpage++;} else if (Offset > 0) {m_curpage--;} if (M_curpage < 0) {m_curpage = 0;} else if (M_curpage > 2) {m_curpage = 2;} Auto Adjustpoint = VEC2 (-m_viewsize.width * m_curpage,0); M_scrollview->setcontentoffsetinduration (AdjustPoint, 0.1f);}
Some of the code that is not listed is as follows:
tableviewcell* Combineview::tablecellatindex (TableView *table, ssize_t idx) {Auto cell = Table->dequeuecell (); auto cellsize = this->tablecellsizeforindex (table, idx), auto tag = Table->gettag (), if (!cell) {cell = new Tableviewcell ( ); Cell->autorelease (); Sprite * PCELLBG = NULL; Label * Pnum = NULL; Sprite * PIcon = Null;switch (tag) {Case TABLE_LEFT:{PCELLBG = sprite::create ("combineview/cell.png");p num = Label:: Createwithttf ("1", "Fonts/marker Felt.ttf",);p icon = sprite::create ("Combineview/book.png");} Break;case TABLE_CENTER:{PCELLBG = sprite::create ("combineview/cell2.png");p num = Label::createwithttf ("2", "fonts/ Marker Felt.ttf ",";p icon = sprite::create ("Combineview/plane.png");} Break;case TABLE_RIGHT:{PCELLBG = sprite::create ("combineview/cell3.png");p num = Label::createwithttf ("3", "fonts/ Marker Felt.ttf ",";p icon = sprite::create ("Combineview/setting.png");} Default:break;} Pcellbg->setposition (VEC2 (CELLSIZE.WIDTH/2,CELLSIZE.HEIGHT/2)); Cell->addchild (PCELLBG);p num->setcolor (color3b (255,0,0));p num->setposition (VEC2 (Cellsize.width * 0.1,cellsize.height/2));cell-> AddChild (Pnum);p icon->setposition (VEC2 (Cellsize.width * 0.85,cellsize.height/2));p Icon->setscale (0.2); Cell->addchild (PIcon);} return cell;}
void Combineview::settouch (bool istouched) {m_lefttable->settouchenabled (istouched);m_centertable-> Settouchenabled (istouched); m_righttable->settouchenabled (istouched);}
Finally, it's over ... It's weird!
The code actually has the problem, I intentionally left a bug, did not know that everybody found no, this bug does not solve, the program runs up will crash. If I ran my previous code, it would crash in the Tablecellatindex function. Because when we created TableView, the tag for each tableview was not successful, why didn't it succeed? Because we have not set the tag, Tablecellatindex this will run up, we pass the Table->gettag (), in fact, is not able to get the tag, since it can not be taken, then cannot create the picture text, will call the null pointer, So the program is boom. Then the culprit is tableview::create (this,viewsize); This guy, we debug tracking into the source code, as follows:
tableview* tableview::create (tableviewdatasource* dataSource, size size, Node *container) { TableView *table = new TableView (); Table->initwithviewsize (size, container); Table->autorelease (); Table->setdatasource (DataSource); Table->_updatecellpositions (); Table->_updatecontentsize (); return table;}
The penultimate sentence is table->_updatecontentsize (), which invokes the Tablecellatindex function. Then find the problem how to solve it, difficult to understand to change the source code? No, we can create the TableView as follows:
M_righttable = Tableview::create (this, viewsize); m_righttable = new TableView (); M_righttable->initwithviewsize ( M_viewsize, NULL); M_righttable->autorelease (); M_righttable->setdatasource (this);
Then why not put Table->_updatecellpositions (), also get in, because this is the protection of member functions, so can not access, but also not used, and later encountered similar problems can be resolved. Then turn three tableview to be OK.
Code and resources download: http://download.csdn.net/detail/sharing_li/8345111
Mixed use of cocos2dx TableView and ScrollView