티스토리 뷰

UIView 를 다루다 보면 layer라는 인스턴스에 접근하게 될 때가 있다. 이 layer는 CALayer의 인스턴스로 iOS나 OS X가 화면에 컨텐츠를 그릴 때 사용하는 class다. UIView로 내용을 그리는 줄 알았는데, UIView는 이 CALayer를 좀 더 쉽게 다룰 수 있게 하는 일종의 wrapper class였던 것이다.

그래서 이 CALayer라는 것을 알아보았다. UIView보다 좀 더 로우 레벨에서 CPU에 부담을 주지 않고, 더 자유로운 그래픽 출력을 할 수 있다고 한다. CALayer의 CA는 Core Animation의 약자로 CAAnimation으로 만들 수 있는 property로 구성된 class다. 다시 말해서 CALayer가 가지고 있는 대부분의 property들은 animate시킬 수 있다는 뜻이고, 이들은 모두 apple developer library에 작성되어 있다.

UIView에서 많이 봤던 이름을 볼 수 있다. 하지만 UIView.animate로 animate시켜보면 duration이 적용이 안되는데, 그 이유는 좀 더 연구해 봐야 겠다.

간단히 색깔을 바꾸는 animation을 만들어 보자.

 

let layer = CALayer()
layer.frame = CGRect(x: 100, y: 100, width: 100, height: 100)
layer.backgroundColor = UIColor.red.cgColor
view.layer.addSublayer(layer)

let animation = CABasicAnimation(keyPath: "backgroundColor")
animation.fromValue = UIColor.red.cgColor
animation.toValue = UIColor.blue.cgColor
animation.duration = 2
layer.add(animation, forKey: "backgroundColor")

 

특이한 점은 key를 단순 문자열로 처리한다는 점인데, enum을 쓰지 않고 단순히 문자열로만 처리하면 오타 때문에 오류가 나기 쉽상인데 왜 이렇게 만들었는지 모르겠다. 심지어 잘못된 property 이름을 입력해도 string 이기 때문에 컴파일 시점에 캐치할 수도 없다.

 

색이 다시 돌아온다.

 

아무튼 이렇게 animate를 시켜 보면 2초동안 파란색으로 바뀌다가 끝나면 다시 빨간색으로 돌아온다. CAAnimation은 duration동안 변화를 시킬 뿐, 실제로 값을 바꾸지는 않기 때문에 toValue로 고정되어야 한다면 animation을 추가하기 전에 최종 색을 정해주어야 한다.

 

layer.backgroundColor = UIColor.blue.cgColor
layer.add(animation, forKey: "backgroundColor")

 

최종 값이 유지된다.

 

 

 

CAShapeLayer

CALayer를 상속받는 여러 Layer들이 제공하는데, CATextLayer의 경우 문자열을 출력할 수 있고, CAEmitterLayer의 경우 파티클을 화면에 출력할 수 있다. 그 중 모양을 출력할 수 있는 CAShapeLayer를 가지고 서서히 차오르는 게이지를 만들어 보자.

 

동그랗게 차오르는 게이지를 CAShapeLayer로 구현한다.

 

CAShapeLayer는 CGPath를 입력받아서 화면에 그린다. 따라서 원을 그리려면 원에 해당하는 Path를 만들어서 입력해 주면 된다. 기본 CGPath의 생성자에서 타원을 만들 수는 있지만 여기서 요구하는 원은 아래가 뚫린 원, 정확히는 호 이기 때문에 UIBezierPath로 아래가 뚫린 호를 생성한다.

 

let arc = UIBezierPath(arcCenter: center, radius: radius, startAngle: CGFloat.pi * 3 / 4, endAngle: CGFloat.pi / 4, clockwise: true)
gaugeLayer.path = arc.cgPath

 

CAShapeLayer는 path정보를 가지고 화면을 그린다.

 

게이지를 그리는데 필요한건 stroke이다. 불필요한 fillColor등을 지우고 굵게 표현하기 위해서 lineWidth, lineCap을 설정한다. lineCap의 경우 .butt이랑 .square가 거의 똑같아 보이는데 선 끝 표현 여부에 따라 조금 차이가 있다.

butt(왼쪽), square(오른쪽)

 

CAShapeLayer가 Path를 따라 그리는 선을 stroke라고 하는데, path의 시작점과 끝 점에 대응하는 strokeStart와 strokeEnd가 있다. 이 property 또한 animate가 가능하기 때문에 이걸 가지고 점점 차오르는 게이지를 만들 수 있다.

 

let gaugeAnimation = CABasicAnimation(keyPath: "strokeEnd")
gaugeAnimation.fromValue = 0
gaugeAnimation.toValue = toValue
gaugeAnimation.duration = 3 * toValue
gaugeLayer.add(gaugeAnimation, forKay: "strokeEnd")

 

strokeStart, strokeEnd는 모두 path에서 상대적인 위치를 나타내기 때문에 시작점은 0, 끝 점은 1이다.

 

strokeColor도 같은 방법으로 animate 시킬 수 있다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함