CCScrollView 的隐藏属性 —— 缩放
来源:互联网 发布:java ee是什么 编辑:程序博客网 时间:2024/06/05 18:23
遇到一个很神奇的事情,之前的项目里面,有一个主地图的缩放功能,类似COC背景地图,可以拖动,可以双指缩放。
一般说来,我们会想到写个layer通过多点触控自己实现,因为现有的引擎提供的组件没有能实现这个功能的(或者说我以前不知道。。。),但是我看这个项目代码的时候发现,整个工程里面,所有的touchmode全是kccOneByOne,也就是说全是单点模式,但是他确实用的是scrollView,确实能实现双指缩放。好神奇。
然后我深入这个事情之后,发现了一系列颠覆我世界观的事情~~~
先说scrollView,其实scrollView一直可以支持缩放,只不过被的隐藏了。在scrollView的代码的touchBegan里面,可以看到如下代码(引擎版本3.4,2.x的同理):
bool ScrollView::onTouchBegan(Touch* touch, Event* event){ ... ... if (std::find(_touches.begin(), _touches.end(), touch) == _touches.end()) { _touches.push_back(touch); } if (_touches.size() == 1) { // scrolling _touchPoint = this->convertTouchToNodeSpace(touch); _touchMoved = false; _dragging = true; //dragging started _scrollDistance = Vec2(0.0f, 0.0f); _touchLength = 0.0f; } else if (_touches.size() == 2) { _touchPoint = (this->convertTouchToNodeSpace(_touches[0]).getMidpoint( this->convertTouchToNodeSpace(_touches[1]))); _touchLength = _container->convertTouchToNodeSpace(_touches[0]).getDistance( _container->convertTouchToNodeSpace(_touches[1])); _dragging = false; } return true;}无关代码已经被省略,可以看到这里面有一个关于触摸点数量的判断,然后还有很多类似的代码(这里涉及一个诡异的问题):
void setZoomScale(float s); void setZoomScale(float s, bool animated); float getZoomScale(); void setZoomScaleInDuration(float s, float dt);zoom的意思显然是缩放。
从touchBegan里面可以看出,这里有一个多点判断,断点size=2的那个分支,发现不能命中断点。把设备打开多点模式,ios需要设置一下glview,具体请百度。发现断点可以成功命中,说明这一步正常。
但是这个时候还是不能缩放,继续跟,发现touchMove里面如下代码:
void ScrollView::onTouchMoved(Touch* touch, Event* event){ ... ... else if (_touches.size() == 2 && !_dragging) { const float len = _container->convertTouchToNodeSpace(_touches[0]).getDistance( _container->convertTouchToNodeSpace(_touches[1])); this->setZoomScale(this->getZoomScale()*len/_touchLength); } ... ...}会调用setZoomScale:
void ScrollView::setZoomScale(float s){ ... ... _container->setScale(MAX(_minScale, MIN(_maxScale, s))); ... ...}
关键就是设置这个container的scale,里面涉及3个变量,一个是传入的想设置的scale,一个是minScale,一个是maxScale,但是max和min在初始化的时候,都被设置成了1。那么这个表达式 MAX(minscale , MIN(maxscale , s)) 的值,就会恒等为1。
所以只要我们能让这个表达式的值发生变化,是不是就可以了?还真是这样。 不幸的是,这个maxscale和minscale的定义,是protect,并且没有提供任何访问函数。。。所以要么直接改掉源代码,要么继承一个子类,提供2个访问函数,来设置这2个值就可以了。
乱入:在3.4的代码里面,已经有这2个值的访问函数,2.x的没有
PS:无责任剧透,据说缩放的时候会有些位移的问题,把container的anchor设置为(0,0)可以解决。我没测,不知道
总结:
1、scrollView实现了双指缩放功能,但是被隐藏
2、打开设备多点触控,并且设置minscale和maxscale,即可使用缩放功能(设置方法见上文)
3、参考上面PS内容。
诡异问题:为什么是单点的触摸模式,确可以达到2点缩放的效果?请看这里!
- CCScrollView 的隐藏属性 —— 缩放
- 隐藏webView的缩放按钮
- CCScrollView的例子
- CCScrollView的使用
- CCScrollView 的坑
- cocos2dx-CCScrollView的制作
- 图片的各种缩放属性
- 属性动画缩放的util
- 隐藏百度地图的缩放按钮
- 讲述属性动画的使用 —使用动画旋转、平移、渐变和缩放
- cocos2dx基础篇(16)——滚动视图CCScrollView
- 图示CCScrollView的相关概念
- ObjectAnimator 属性动画 缩放, ViewAnimator的用法
- webview设置缩放属性的方法
- 显示隐藏控件的属性
- 如何隐藏published的属性
- 修改文件的隐藏属性
- android 控件的隐藏属性 .
- IOS 消息机制(NSNotificationCenter)
- ORACLE EXP IMP 导入导出数据 解决如何导出空表
- mysql localhost与127.0.0.1以及ip连接的区别
- xinetd
- 基于Netty的Comet测试及调优
- CCScrollView 的隐藏属性 —— 缩放
- 各种guard
- 优化之“股票配资”的策略与记录
- CMake官方文档
- 自己动手在CentOS 7上编译安装GCC 4.9.2
- Android 自定义 ViewPager 打造千变万化的图片切换效果
- JAVA应用程序获取当前路径
- linux下FTP
- POJ 3666 Making the Grade (DP+离散化)