实现思路:
扇形动画分为4部分,先将4个View加入视图,横向重叠展示,然后修改view的锚点为最右侧中心点,同一时间进行角度不同的旋转动画,就实现了展开效果.view上如果加入子View.也需要将其旋转90度使其横向展示
实现方式:
- 创建扇形ImageView。
- 添加4个扇形View,一个动画开始关闭按钮。
- 实现动画方法.
1.创建扇形ImageView
为其修改锚点为最右侧中心点。为扇形ImageView添加子View.同时将子View旋转90度,以保证与扇形View同方向展示。为扇形ImageView添加闭包回调。
class EWArcAnimationSubImageView: UIImageView {
public var backClick: (()->())?
private let imageView: UIImageView = {
let imageView = UIImageView(frame: CGRect(x: 5, y: 30.75, width: 33, height: 33))
imageView.transform = CGAffineTransform(rotationAngle: -.pi/2)
return imageView
}()
private let label: UILabel = {
let label = UILabel(frame: CGRect(x: 35, y: 0, width: 40, height: 94.5))
label.textColor = UIColor.black
label.textAlignment = .center
label.transform = CGAffineTransform(rotationAngle: -.pi/2)
return label
}()
private let button: UIButton = {
let button = UIButton(frame: CGRect(x: 0, y: 22.25, width: 60, height: 50))
return button
}()
override init(frame: CGRect) {
super.init(frame: frame)
drawMyView()
}
init(frame: CGRect, title: String, image: String, backImage: String) {
super.init(frame: frame)
drawMyView()
self.label.text = title
self.imageView.image = UIImage(named: image)
self.image = UIImage(named: backImage)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
private func drawMyView(){
self.alpha = 0
self.layer.anchorPoint = CGPoint(x: 1, y: 0.485)
self.isUserInteractionEnabled = true
self.addSubview(imageView)
self.addSubview(label)
self.addSubview(button)
button.addTarget(self, action: #selector(onClickSubButton), for: .touchUpInside)
}
@objc private func onClickSubButton(){
if backClick != nil {
backClick!()
}
}
}
2.添加4个扇形View,一个动画开始关闭按钮。
private lazy var homeButton: EWArcAnimationSubImageView = {
let view = EWArcAnimationSubImageView(frame:CGRect(x: 60.3, y: 69, width: 120.6, height: 94.5), title: "首页", image: "ArcAnimation_home", backImage: "ArcAnimation_white")
view.backClick = { [weak self] in
if self?.backType != nil{
self?.backType!("首页")
}
}
return view
}()
private lazy var nameButton: EWArcAnimationSubImageView = {
let view = EWArcAnimationSubImageView(frame:CGRect(x: 60.3, y: 69, width: 120.6, height: 94.5), title: "姓名", image: "ArcAnimation_name", backImage: "ArcAnimation_pink")
view.backClick = { [weak self] in
if self?.backType != nil{
self?.backType!("姓名")
}
}
return view
}()
private lazy var industrybutton: EWArcAnimationSubImageView = {
let view = EWArcAnimationSubImageView(frame:CGRect(x: 60.3, y: 69, width: 120.6, height: 94.5), title: "行业", image: "ArcAnimation_industry", backImage: "ArcAnimation_white")
view.backClick = { [weak self] in
if self?.backType != nil{
self?.backType!("行业")
}
}
return view
}()
private lazy var locationButton: EWArcAnimationSubImageView = {
let view = EWArcAnimationSubImageView(frame:CGRect(x: 60.3, y: 69, width: 120.6, height: 94.5), title: "地址", image: "ArcAnimation_location", backImage: "ArcAnimation_pink")
view.backClick = { [weak self] in
if self?.backType != nil{
self?.backType!("地址")
}
}
return view
}()
private let setingButton: UIButton = {
let button = UIButton(frame: CGRect(x: 235 - 79 - 68, y: 190 - 32 - 68, width: 68, height: 68))
button.setImage(UIImage(named: "CircleSelect_select"), for: .normal)
button.setImage(UIImage(named: "CircleSelect_select"), for: .selected)
return button
}()
override init(frame: CGRect) {
super.init(frame: frame)
drawMyView()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func drawMyView() {
self.addSubview(homeButton)
self.addSubview(nameButton)
self.addSubview(industrybutton)
self.addSubview(locationButton)
self.addSubview(setingButton)
setingButton.addTarget(self, action: #selector(onClickSetingButton), for: .touchUpInside)
}
3.实现动画方法.
@objc private func onClickSetingButton() {
setingButton.isSelected = !setingButton.isSelected
if setingButton.isSelected {
show()
}else {
hidden()
}
}
@objc private func show() {
/// 保证动画在非进行中
guard self.isAnimationIng == false else { return }
/// 分别设定三个imageView的旋转角度
let transform1 = CGAffineTransform(rotationAngle: .pi/4)
let transform2 = CGAffineTransform(rotationAngle: .pi/2)
let transform3 = CGAffineTransform(rotationAngle: .pi/4*3)
/// 关键帧动画
UIView.animateKeyframes(withDuration: 1.5, delay: 0, options: [.allowUserInteraction], animations: {
/// 动画进行中
self.isAnimationIng = true
/// 添加关键帧, 在前0.2秒将View展示
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.2, animations: {
self.homeButton.alpha = 1
self.nameButton.alpha = 1
self.industrybutton.alpha = 1
self.locationButton.alpha = 1
})
/// 在1.5秒时间进行旋转动画
self.nameButton.transform = transform1
self.industrybutton.transform = transform2
self.locationButton.transform = transform3
}) { (_) in
/// 结束时设置动画进行中状态为False
self.isAnimationIng = false
}
}
@objc private func hidden(){
/// 保证动画在非进行中
guard self.isAnimationIng == false else { return }
/// 关键帧动画
UIView.animateKeyframes(withDuration: 1.5, delay: 0, options: [.allowUserInteraction], animations: {
/// 动画进行中
self.isAnimationIng = true
/// view展开状态
/// 将View复原
self.nameButton.transform = CGAffineTransform.identity
self.industrybutton.transform = CGAffineTransform.identity
self.locationButton.transform = CGAffineTransform.identity
self.homeButton.alpha = 0
self.nameButton.alpha = 0
self.industrybutton.alpha = 0
self.locationButton.alpha = 0
}) { (_) in
/// 结束时设置动画进行中状态为False
self.isAnimationIng = false
}
}
demo地址:EWArcAnimation
有问题欢迎探讨.