iOS中围绕支点旋转ImageView及录音时环形SeekBar旋转填充问题
1. 如何在iOS中围绕支点旋转ImageView?
要实现围绕自定义支点旋转ImageView,核心是先设置视图的锚点(anchorPoint),再应用旋转变换就行,我给你拆解具体步骤:
- 首先,UIView默认的锚点是(0.5, 0.5)(也就是视图中心),如果要改成其他支点,直接修改layer的anchorPoint。但要注意:修改锚点会让视图的位置发生偏移,所以得同时调整position来修正,保证视图还在原来的位置。
- 然后用
CGAffineTransform做2D旋转,或者CATransform3D做带透视的3D旋转。
举个Swift代码示例,比如让ImageView围绕左下角旋转45度:
// 假设你的ImageView实例是imageView // 设置锚点为左下角(x:0, y:1) imageView.layer.anchorPoint = CGPoint(x: 0, y: 1) // 调整position修正位置偏移 imageView.layer.position = CGPoint(x: imageView.bounds.minX, y: imageView.bounds.maxY) // 应用45度旋转(转成弧度) let rotationAngle = CGFloat.pi / 4 imageView.transform = CGAffineTransform(rotationAngle: rotationAngle)
如果要做动画旋转,用UIView的动画包裹一下就行:
UIView.animate(withDuration: 0.5) { self.imageView.transform = CGAffineTransform(rotationAngle: CGFloat.pi / 2) // 90度 }
要是需要3D旋转效果(比如带透视的翻转),可以用CATransform3D:
var transform = CATransform3DIdentity transform.m34 = -1.0 / 500.0 // 添加轻微透视,数值越小透视越强 transform = CATransform3DRotate(transform, CGFloat.pi, 0, 1, 0) // 绕Y轴旋转180度 imageView.layer.transform = transform
2. 录音App中实现SeekBar小圆圈沿虚线圆环平滑旋转+填充效果
这个需求分两部分:小圆圈沿路径移动、同步填充虚线圆环,我给你一步步实现:
第一步:绘制背景虚线圆环
先创建一个CAShapeLayer来画虚线圆环,作为背景:
// 定义圆环的中心、半径,路径从顶部开始(-π/2对应12点钟方向) let circleCenter = CGPoint(x: view.bounds.midX, y: view.bounds.midY) let circleRadius: CGFloat = 100 let circlePath = UIBezierPath(arcCenter: circleCenter, radius: circleRadius, startAngle: -CGFloat.pi / 2, endAngle: 3 * CGFloat.pi / 2, clockwise: true) // 创建虚线圆环图层 let dashedCircleLayer = CAShapeLayer() dashedCircleLayer.path = circlePath.cgPath dashedCircleLayer.strokeColor = UIColor.lightGray.cgColor dashedCircleLayer.fillColor = UIColor.clear.cgColor dashedCircleLayer.lineWidth = 4 dashedCircleLayer.lineDashPattern = [8, 4] // 控制虚线的线段长度和间隔 view.layer.addSublayer(dashedCircleLayer)
第二步:让小圆圈沿圆环平滑移动
先添加小圆圈视图,再用CAKeyframeAnimation让它沿着圆环路径运动:
// 创建小圆圈指示器 let indicatorView = UIView(frame: CGRect(x: 0, y: 0, width: 20, height: 20)) indicatorView.backgroundColor = UIColor.systemBlue indicatorView.layer.cornerRadius = 10 // 初始位置放在圆环顶部 indicatorView.center = CGPoint(x: circleCenter.x, y: circleCenter.y - circleRadius) view.addSubview(indicatorView) // 创建路径动画 let pathAnimation = CAKeyframeAnimation(keyPath: "position") pathAnimation.path = circlePath.cgPath pathAnimation.duration = 30 // 对应30秒录音时长,速度均匀 pathAnimation.repeatCount = 0 // 只执行一次 pathAnimation.calculationMode = .paced // 保证动画速度恒定,不会忽快忽慢 indicatorView.layer.add(pathAnimation, forKey: "circlePathAnimation")
第三步:同步填充虚线圆环
用另一个CAShapeLayer作为填充层,随着录音进度更新strokeEnd来实现填充效果:
// 创建填充用的圆环图层(和背景圆环完全重合) let fillCircleLayer = CAShapeLayer() fillCircleLayer.path = circlePath.cgPath fillCircleLayer.strokeColor = UIColor.systemBlue.cgColor fillCircleLayer.fillColor = UIColor.clear.cgColor fillCircleLayer.lineWidth = 4 fillCircleLayer.strokeStart = 0 fillCircleLayer.strokeEnd = 0 // 初始无填充 fillCircleLayer.lineCap = .round // 可选,让填充端点更圆润 view.layer.addSublayer(fillCircleLayer)
然后在录音过程中,实时计算进度并更新strokeEnd。比如用Timer配合AVAudioRecorder的currentTime:
// 假设你已经初始化了audioRecorder let progressTimer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in guard let recorder = self.audioRecorder, recorder.isRecording else { timer.invalidate() return } // 计算录音进度(当前时间/总时长30秒) let progress = recorder.currentTime / 30.0 self.fillCircleLayer.strokeEnd = CGFloat(progress) }
这样小圆圈的移动和圆环填充就能和录音进度完全同步啦~
内容的提问来源于stack exchange,提问作者Zahid Usman Cheema
相关产品推荐
相关产品推荐

