[iOS] - CAGradientLayer, 그라데이션 적용하기


view에 그라데이션을 적용해보자.


CAGradientLayer

얘는 둥근 모서리를 가진 레이어까지 포함해서 모양 내의 배경을 그라데이션으로 채우는 레이어이다. 참고로 iOS 3.0부터 사용 가능하니 걱정하지 않고 사용하면 되겠다.

이 그라데이션 레이어를 사용해서 여러 색을 그라데이션으로 표현한다. 기본적으로 색깔들은 레이어 내에 균일하게 뿌려지지만, 각 색의 포지션을 따로 정의할 수도 있다.

gradientLayer.colors = [UIColor.red.cgColor,
                        UIColor.yellow.cgColor,
                        UIColor.green.cgColor,
                        UIColor.blue.cgColor]

gradientLayer.transform = CATransform3DMakeRotation(CGFloat.pi / 2, 0, 0, 1)

위 코드는 4개의 색을 그라데이션 레이어에 포함시키는 코드이다. 레이어를 90도(pi / 2)는 수평적인 그라데이션을 연출한다. 화면에는 아래와 같이 나타나게 된다.

image

프로퍼티에는 아래와 같은 것들이 있다.

image

먼저 그라데이션을 갖는 간단한 view를 구현해보았다.

private lazy var testView: UIView = {
    let view = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))

    view.translatesAutoresizingMaskIntoConstraints = false

    view.layer.borderWidth = 2
    view.layer.borderColor = UIColor.black.cgColor

    let gradientLayer = CAGradientLayer()
    gradientLayer.frame = view.layer.bounds
    gradientLayer.colors = [UIColor.systemRed.cgColor, UIColor.systemYellow.cgColor, UIColor.systemOrange.cgColor]

    view.layer.insertSublayer(gradientLayer, at: 0)
    return view
}()

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    view.backgroundColor = .white

    view.addSubview(testView)

    testView.heightAnchor.constraint(equalToConstant: 100).isActive = true
    testView.widthAnchor.constraint(equalToConstant: 100).isActive = true
    testView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    testView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
}

image

보니 그라데이션 레이어 자체의 frame은 처음 설정할 때 정해지고, 이후 그라데이션이 적용된 view의 contraint가 바뀌어도 이에 맞게 같이 따라가지는 않는 듯 했다.

startPoint, endPoint

image

그라데이션 레이어의 startPointendPoint를 지정하지 않았을 때의 default 그라데이션 방향은 위와 같이 수직 방향으로 위에서부터 아래로 그라데이션이 적용되는 형태로 나오는 듯 하다.

하지만 코드를 아래와 같이 바꿔서 startPointendPoint를 임의로 지정해주면 그라데이션의 방향이 바뀌게 된다.

gradientLayer.startPoint = CGPoint(x: 0, y: 1)
gradientLayer.endPoint = CGPoint(x: 1, y: 1)

image

gradientLayer.startPoint = CGPoint(x: 0, y: 0)
gradientLayer.endPoint = CGPoint(x: 1, y: 1)

image

그라데이션의 방향을 설정하고 싶을 때 startPoint, endPoint를 사용하면 되는데, startPoint의 기본값은 (0.5, 0), endPoint의 기본값은 (0.5, 1.0)이다. 그래서 아무 값도 설정하지 않았을 때 위에서 아래 방향으로 그라데이션이 그려졌던 것이다.

image

그래서 원하는 방향에 맞게 이 point들을 설정해주면 된다.

location

location은 말 그대로 색의 위치를 설정할 수 있는 프로퍼티이다. 각 gradient가 멈추는 location을 의미하는데, 0 ~ 1 사이의 값을 가지고, 꼭 증가해야 한다.

그래서 [1.0, 0.8, 0.5]이렇게 하면 안되고 [0.5, 0.8, 1.0] 이렇게 설정해야 한다.

만약에 location에 값을 지정하지 않은 default 상태에서는 범위 전체에 균일하게 분산된다고 한다.

변화를 한 번에 확인하기 쉽게 색을 순서대로 빨강, 파랑, 보라색으로 그라데이션을 설정했다. 그러면 point도 따로 지정하지 않은 기본 상태는 아래와 같이 나온다.

image

이제 location을 [1]으로 설정해보겠다. 이러면 색이 총 3개가 있는데, 첫 번째 요소의 색이 멈추는 지점을 1 으로 설정했으니 빨간색만 화면에 나오게 되는 것이다.

image

[0]으로도 설정해봤는데, 내가 예상한 동작은 빨간색이 나오지 않고 파랑 -> 보라만 나오는 것이었으나 실제로는 아래와 같이 마지막 색깔인 보라색만이 나오지 않았다.

image

[0.5] 이렇게 지정하면 빨간색이 0.5 지점에서 멈추고, 파란색만이 나오게 된다. 아마 파란색이 끝나는 지점을 지정해주지 않아서 나머지가 다 파란색으로 채워지는 느낌이다.

image

type

image

type에는 총 3가지가 있는데,

  • axial : linear. 두 endPoint 사이의 축을 따라 달라진다. 축에 수직인 선 위에 있는 모든 점들은 동일한 색상을 갖는다. 기본값이 된다.
  • conic : 아래와 같은 동그란 애들이다. image
  • radial

conic의 경우 startPointendPoint를 잡아주지 않고 그냥 사용하게 되면 아래와 같이 나온다.

image

gradientLayer.startPoint = CGPoint(x: 0.5, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 0)

위와 같이 설정해야지 아래와 같이 동그란 형태의 그라데이션이 나오게 된다.

image

radial의 경우 아래와 같은 방사형이다.

image

얘도 마찬가지로 startPointendPoint를 잘 잡아줘야 한다.

gradientLayer.startPoint = CGPoint(x: 0.5, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1, y: 1)

image

Zedd님께서 올려주신 gist를 화면에 출력하니 아래와 같이 나왔다.

gradation

이렇게 애니메이션과 같이 아주 멋진 그래픽을 연출할 수 있는데, 애니메이션도 공부해야 할 것 같다.