先来看看效果:
下面进入正题,是时候展现真正的技术了:
首先在控制器里添加一个scrollview,再在scrollview上的对应位置上添加要展示的imageview(立方体视图组),当然也可以放上其它子控制器的view实现更多功能这个随意不是重点
//*******添加scrollview******* [self createscrollview]; //******创建立方体视图组****** [self createcubicviewarray];
//添加视图到scrollview上 for (int i=0; i<_viewarray.count; i++) { uiimageview *transview=_viewarray[i]; //视图在scrollview上对应的位置 transview.x=self.view.bounds.size.width * i;
监听scrollview的滑动事件,在这里要先获取到显示的当前页、上一页、下一页,然后让这三个页面同时做3dtransform变换
#pragma mark - scrollview滑动事件 -(void)scrollviewdidscroll:(uiscrollview *)scrollview{ //当前页数 nsinteger currentpage=_currentpage; //当前视图 uiview *currentview=_viewarray[currentpage]; //上一个视图 uiview *lastview=nil; if (currentpage-1>=0) { lastview=_viewarray[currentpage-1]; } //下一个视图控制器视图 uiview *nextview; if (currentpage+1<=3) { nextview=_viewarray[currentpage+1]; } //本次偏移距离 cgfloat currentoffset=scrollview.contentoffset.x-currentpage*self.view.bounds.size.width; //本次偏移角度 cgfloat deltaangle=currentoffset/self.view.bounds.size.width * m_pi_2; //****************当前视图移动变幻*************** //设置锚点 currentview.layer.anchorpoint=cgpointmake(0.5, 0.5); //向屏幕前方移动 catransform3d move = catransform3dmaketranslation(0, 0, self.view.bounds.size.width/2); //旋转 catransform3d rotate = catransform3dmakerotation(-deltaangle, 0, 1, 0); //平移 catransform3d plaintmove=catransform3dmaketranslation( currentoffset, 0, 0); //向屏幕后方移动 catransform3d back = catransform3dmaketranslation(0, 0, -self.view.bounds.size.width/2); //连接 catransform3d concat=catransform3dconcat( catransform3dconcat(move, catransform3dconcat(rotate, plaintmove)),back); catransform3d transform=catransform3dperspect(concat, cgpointmake(currentoffset/2, self.view.bounds.size.height), 5000.0f); //添加变幻特效 currentview.layer.transform=transform; //****************下一个视图移动变幻*************** //设置锚点 nextview.layer.anchorpoint=cgpointmake(0.5, 0.5); //向屏幕前方移动 catransform3d move2 = catransform3dmaketranslation(0, 0, self.view.bounds.size.width/2); //旋转 catransform3d rotate2 = catransform3dmakerotation(-deltaangle+m_pi_2, 0, 1, 0); //平移 catransform3d plaintmove2=catransform3dmaketranslation( currentoffset-self.view.bounds.size.width, 0, 0); //向屏幕后方移动 catransform3d back2 = catransform3dmaketranslation(0, 0, -self.view.bounds.size.width/2); //拼接 catransform3d concat2=catransform3dconcat( catransform3dconcat(move2, catransform3dconcat(rotate2, plaintmove2)),back2); catransform3d transform2=catransform3dperspect(concat2, cgpointmake(self.view.bounds.size.width/2+currentoffset/2, self.view.bounds.size.height), 5000.0f); //添加变幻特效 nextview.layer.transform=transform2; //****************上一个视图移动变幻*************** //设置锚点 lastview.layer.anchorpoint=cgpointmake(0.5, 0.5); //向屏幕前方移动 catransform3d move3 = catransform3dmaketranslation(0, 0, self.view.bounds.size.width/2); //旋转 catransform3d rotate3 = catransform3dmakerotation(-deltaangle-m_pi_2, 0, 1, 0); //平移 catransform3d plaintmove3=catransform3dmaketranslation( currentoffset+self.view.bounds.size.width, 0, 0); //向屏幕后方移动 catransform3d back3 = catransform3dmaketranslation(0, 0, -self.view.bounds.size.width/2); //拼接 catransform3d concat3=catransform3dconcat(catransform3dconcat(move3, catransform3dconcat(rotate3, plaintmove3)),back3); catransform3d transform3=catransform3dperspect(concat3, cgpointmake(-self.view.bounds.size.width/2+currentoffset/2, self.view.bounds.size.height), 5000.0f); //添加变幻特效 lastview.layer.transform=transform3; }
这里记得要复原一下3d变换,不然滑快了会出现页面错乱
-(void)scrollviewdidenddecelerating:(uiscrollview *)scrollview{ //改变选中页序号 [self changeindex]; //3d变幻恢复原状态 for (uiview * view in _viewarray) { view.layer.transform=catransform3didentity; } }
对了,记得添加一个很重要的透视变换函数,核心在于仿射矩阵的m34属性,这样才会产生远小近大的3d效果,让动画更炫酷
//3d透视函数 catransform3d catransform3dmakeperspective(cgpoint center, float disz) { catransform3d transtocenter = catransform3dmaketranslation(-center.x, -center.y, 0); catransform3d transback = catransform3dmaketranslation(center.x, center.y, 0); catransform3d scale = catransform3didentity; scale.m34 = -1.0f/disz; return catransform3dconcat(catransform3dconcat(transtocenter, scale), transback); }
这一篇文章就到这里了,大家有什么意见和问题记得及时反馈,希望本文对大家开发ios有所帮助。
如对本文有疑问, 点击进行留言回复!!
iOS开发苹果开发者企业账号续费(提示你的支付授权失败解决办法)
有关ios::sync_with_stdio(false)和cin.tie(nullptr)的介绍与意义
iOS14有nfc功能吗 iOS14 nfc功能开启关闭方法
网友评论