2021. 1. 8. 00:33ㆍiOS
오늘은 저번 시간에 이어 CABasicAnimation을 활용해서 새로운 애니메이션을 만들어 보았어요..!!
카카오톡에서 더보기 탭의 여러 메뉴들을 클릭하고 데이터를 받아올 때, 로딩화면이 있더라구요..?
저는 항상 이런것도 디자이너한데 부탁해서 Air BnB-Lottie를 이용해서 구현했는데, CABasicAnimation을 사용하고 보니깐 이것도 할 수 있겠다 생각이 들어서 바로 만들어봤어요.
먼저 화면을 먼저 보여드리면 다음과 같아요.
요런화면 어떤 요청을 보낼 때 본적 있죠?
오늘은 저걸 만들어볼게요!!
구현 방법
이 화면에서는 구현해야 할 UI요소가 몇가지일까요..?
저는 크게 2가지로 구성을 했는데요.
- 진행 트랙을 보여주는 뒤의 Background Layer
- 화면이 돌아가며 진행을 보여주는 Indicator Layer
이렇게 크게 2가지에요.
Q. 어 왜..? 제일 뒤의 회색 화면은 말을 안해요..?
👉 바로 저 부분은 UIView의 backgroundColor와 UIView.layer를 이용해서 기본으로 구성했어요!
그럼 우선 기본 UI를 먼저 구성해볼게요!
처음으로 UIView을 Custom으로 생성해주세요.
// 이름은 자유롭게 해주세요!
class LoadingIndicator: UIView {
}
이제 다음으로 제일 뒤의 화면 배경을 먼저 만들어줄게요! (아직 Layer를 이용하는 것이 아닌 젤 뒤 배경만이에요!)
여기서는 CALayer를 이용하지 않고 UIView.backgroundColor, UIView.layer.borderRadius를 활용할거에요.
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .darkGray
clipsToBounds = true
layer.cornerRadius = frame.width/2
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
backgroundColor = .darkGray
clipsToBounds = true
layer.cornerRadius = frame.width/2
}
이렇게 하면 둥근 배경의 화면만 떴을거에요!
이제는 위에서 언급했던 2가지의 구성요소 있죠?
그 중 첫번째, 진행 트랙을 보여주는 backgroundLayer를 UIBezierPath, CAShapeLayer를 이용해서 생성해줄거에요.
private lazy var backgroundLayer: CAShapeLayer = {
let layer = CAShapeLayer()
layer.lineWidth = 5
layer.strokeColor = UIColor.black.cgColor
layer.fillColor = UIColor.clear.cgColor
layer.lineCap = .round
layer.frame = bounds
return layer
}()
private lazy var circlePath: UIBezierPath = {
let center = CGPoint(x: bounds.width/2, y: bounds.height/2)
let path = UIBezierPath(arcCenter: center,
radius: bounds.width/2*2/3,
startAngle: .pi/2,
endAngle: 2*.pi - .pi/2,
clockwise: true)
return path
}()
override func draw(_ rect: CGRect) {
backgroundLayer.path = circlePath.cgPath
layer.addSublayer(backgroundLayer)
}
draw를 사용해서 커스텀으로 UIView를 그려주었는데요.
개발자 문서에 보면 이 메소드를 이용해서 UIView의 도화지 삼아서 render 시킬 수 있다고 나와있어요!
나머지 그려주는 부분에는 특별한 것이 없어요.
만약 CAShapeLayer를 이용해서 그림을 그려주는 것이 이해가 되지 않으면 앞 글을 보고오면 도움이 될 것 같아요..!!
[iOS] CABasicAnimation 활용(1) - Counting Progress (UIBezierPath, CAShapeLayer)
이전 포스팅에서는 간단하게 CABasicAnimation을 이용해서 할 수 있는 애니메이션을 해보았어요..!! [iOS] CABasicAnimation란 요즘 Core Animation에 관심을 가지면서 Core Animation를 공부해보기위해 간단히 사..
dongminyoon.tistory.com
여기서 radius를 현재 뷰의 반지름으로 설정하지 않은 이유는 젤 위의 애니메이션을 보시면 아시겠죠..?!
실제 트랙으로 나타나는 뷰가 원래 UIView보다 더 작아요!
다음으로 마지막 요소인 Indicator Layer를 만들어볼게요.
여기선 아까 backgroundLayer에서 만들어준 circlePath를 활용할거에요.
단 다른 점은 stokeEnd를 이용해서 끝을 잘라줄거라는거~~
private lazy var indicatorLayer: CAShapeLayer = {
let layer = CAShapeLayer()
layer.strokeColor = UIColor.white.cgColor
layer.fillColor = UIColor.clear.cgColor
layer.lineWidth = 5
layer.lineCap = .round
layer.frame = bounds
// 이 부분을 이용해서 끝을 잘라주었어요!
layer.strokeEnd = 0.35
return layer
}()
override func draw(_ rect: CGRect) {
// circlePath는 아까 위에서 만들었죠.
// 똑같이 사용하면 됩니다.
indicatorLayer.path = circlePath.cgPath
layer.addSublayer(indicatorLayer)
}
자 이렇게까지하면 이제 모든 UI요소들은 만들어주었어요.
마지막으로 이제 애니메이션만 추가해주면 되겠죠?
여기서 CABasicAnimation을 이용할거랍니다!
func startAnimation() {
let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
rotationAnimation.fromValue = 0
rotationAnimation.toValue = 2*.pi
rotationAnimation.duration = 2
rotationAnimation.repeatCount = HUGE
indicatorLayer.add(rotationAnimation, forKey: "rotate")
}
func cancelAnimation() {
layer.sublayers?.forEach { layer in
layer.removeAllAnimations()
layer.removeFromSuperlayer()
}
}
keyPath에는 많은 요소들이 있었는데 중앙을 기준으로 둥글게 둥글게 돌려주면 되어서 transform.rotation을 활용하였습니다.
이렇게까지 해주고 ViewController에서 한 번 생성하고 startAnimation()까지 호출해볼게요!
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let loadingIndicator = LoadingIndicator(frame: CGRect(x: 100, y: 100, width: 200, height: 200))
loadingIndicator.startAnimation()
self.view.addSubview(loadingIndicator)
}
}
여기까지 해주시면 제일 위와 같은 완성된 화면을 보실 수 있을거에요!!
재밌어서 이것저것 만들어보고 있었는데, 다음에는 또 다른 걸 만들어서 와볼게요 ㅎㅎㅎ
그럼 오늘 포스팅은 여기까지 해볼게요! :D
궁금한 점이나 이런 것도 해보면 좋겠어요 등등 다양한 의견있으시면 댓글 달아주세요.
감사합니다!
'iOS' 카테고리의 다른 글
[iOS] TDD와 Unit Test (2) | 2021.02.06 |
---|---|
[iOS] Xcode Target이란? (2) | 2021.02.01 |
[iOS] CABasicAnimation 활용 (1) - Counting Progress (UIBezierPath, CAShapeLayer) (1) | 2021.01.04 |
[iOS] CABasicAnimation란 (0) | 2020.12.31 |
[iOS] CALayer란 (2) | 2020.12.31 |