CLWheelMenuView Swift 转盘菜单开源项目

我要开发同款
匿名用户2020年12月03日
99阅读
开发技术Swift
所属分类Objective-C、菜单(Menu)、iOS代码库
授权协议MIT

作品详情

前言

使用Swift实现的转盘菜单,主要用到UIBezierPath、CALayer遮罩绘制扇形UIView,CATransform3DMakeRotation实现旋转动画。代码设计使用默认configureCallback回调方便创建和设置基本属性,参考UITableView代理和数据源模式,支持AutoLayout和Frame。

效果图

1.遮罩绘制扇形View

计算扇形曲线位置,通过CALayer的mask属性绘制出扇形UIView核心代码

funcsetMaskLayer(_startAngle:CGFloat,endAngle:CGFloat){  letcenter=CGPoint(x:bounds.width*0.5,y:bounds.height*0.5)  letlayer=CAShapeLayer()  path.addArc(withCenter:center,radius:bounds.width*0.5,startAngle:startAngle,endAngle:endAngle,clockwise:true)  path.addLine(to:center)  layer.path=path.cgPath  layer.rasterizationScale=UIScreen.main.scale  layer.shouldRasterize=true  self.layer.mask=layer}2.中间镂空funccreateHole(inview:UIView,radius:CGFloat) {  letpath=CGMutablePath()  path.addArc(center:view.center,radius:radius,startAngle:0.0,endAngle:2.0*.pi,clockwise:true)  path.addRect(CGRect(origin:.zero,size:view.bounds.size))  letmaskLayer=CAShapeLayer()  maskLayer.path=path  maskLayer.fillRule=.evenOdd  view.layer.mask=maskLayer  view.clipsToBounds=true}3.旋转动画

添加UIPanGestureRecognizer、UITapGestureRecognizer手势,根据手势位置使用atan2函数计算旋转角度,然后用CATransform3DMakeRotation围绕Z轴旋转做动画核心代码

funchandlePanGesture(_sender:UIPanGestureRecognizer){  letlocation=sender.location(in:self)  switchsender.state{  case.began:    startPoint=location  case.changed:    letradian1=-atan2(startPoint.x-menuLayerView.center.x,startPoint.y-menuLayerView.center.y)    letradian2=-atan2(location.x-menuLayerView.center.x,location.y-menuLayerView.center.y)    menuLayerView.transform=menuLayerView.transform.rotated(by:radian2-radian1)    startPoint=location  default:    letangle=2*CGFloat(Double.pi)/CGFloat(cells.count)    varmenuViewAngle=atan2(menuLayerView.transform.b,menuLayerView.transform.a)    ifmenuViewAngle<0{      menuViewAngle+=CGFloat(2*Double.pi)    }    varindex=cells.count-Int((menuViewAngle+CGFloat(Double.pi/4))/angle)    ifindex==cells.count{      index=0    }    setSelectedIndex(index,animated:true)  }}funchandleTapGesture(_sender:UITapGestureRecognizer){  letlocation=sender.location(in:menuLayerView)  for(index,cell)incells.enumerated(){    ifcell.path.contains(location){      setSelectedIndex(index,animated:true)    }  }}4.弹出收起动画funcopenMenuView(withAnimateanimate:Bool=true){  openMenu=true  UIView.animate(withDuration:animate?configure.animationDuration:0,delay:0,usingSpringWithDamping:0.7,initialSpringVelocity:5.0,options:.curveEaseInOut){    self.centerButton.transform=CGAffineTransform(rotationAngle:.pi*-0.5)    self.centerButton.setImage(self.configure.closeImage,for:.normal)    self.menuLayerView.transform=CGAffineTransform(scaleX:1,y:1).rotated(by:self.currentAngle)  }}funccloseMenuView(withAnimateanimate:Bool=true){  openMenu=false  letscale=(configure.centerRadius*2)/bounds.width  UIView.animate(withDuration:animate?configure.animationDuration:0,delay:0,usingSpringWithDamping:0.7,initialSpringVelocity:5.0,options:.curveEaseInOut){    self.centerButton.transform=.identity    self.centerButton.setImage(self.configure.openImage,for:.normal)    self.menuLayerView.transform=CGAffineTransform(scaleX:scale,y:scale).rotated(by:self.currentAngle)  }}5.内部细节

考虑到方便布局和使用,内部使用UIView叠加旋转实现,这里也可以采用Layer直接绘制实现,相对UIView,层次结构会简单很多

总结

核心代码已经贴出,完整代码请查看----->>>CLDemo,如果对你有所帮助,欢迎Star。

声明:本文仅代表作者观点,不代表本站立场。如果侵犯到您的合法权益,请联系我们删除侵权资源!如果遇到资源链接失效,请您通过评论或工单的方式通知管理员。未经允许,不得转载,本站所有资源文章禁止商业使用运营!
下载安装【程序员客栈】APP
实时对接需求、及时收发消息、丰富的开放项目需求、随时随地查看项目状态

评论