iOS 응용 (swift)
[iOS - swift] CAGradientLayer, layer.mask (+ 텍스트 gradient fade out 처리)
jake-kim
2021. 3. 26. 02:21



CAGradientLayer이란?

- layer에 색 그라데이션을 입히는데 사용되는 객체
- 주로 UIView나 UILabel의 text에 그라데이션을 입히는데 사용
CAGradientLayer 사용 방법
- 객체 생성 후 frame 설정: frame은 적용될 view의 bounds로 설정
let gradientLayer = CAGradientLayer()
gradientLayer.frame = myView.bounds
- 그라데이션에 들어갈 색상 추가(처음 ~ 마지막 순서대로 기입): 타입은 [CGColor] 타입
gradientLayer.colors = [UIColor.orange.cgColor, UIColor.red.cgColor]
- gradientLayer의 속성을 모두 지정하였으므로 (적용될뷰.layer.addSublayer)로 layer 적용
myView.layer.addSublayer(gradientLayer)
- 전체 코드
let gradientLayer = CAGradientLayer()
gradientLayer.frame = myView.bounds
gradientLayer.colors = [UIColor.orange.cgColor, UIColor.red.cgColor]
myView.layer.addSublayer(gradientLayer)

CAGradientLayer의 속성
- 위의 예제는 색상을 균일하게 등분하여 orange와 red를 5:5로 그라데이션 효과를 적용
- locations속성: 0~1사이의 값을 순서대로 그라데이션이 종료되는 구간을 기입 (디폴트는 세로로 진행)
- 반드시 오름차순으로 기입
let gradientLayer = CAGradientLayer()
gradientLayer.frame = myView.bounds
gradientLayer.colors = [UIColor.orange.cgColor, UIColor.red.cgColor]
gradientLayer.locations = [0.7] // <- 추가
myView.layer.addSublayer(gradientLayer)

gradientLayer.locations = [0.3]

gradientLayer.colors = [UIColor.orange.cgColor, UIColor.red.cgColor, UIColor.black.cgColor]
gradientLayer.locations = [0.3, 0.6]

- startPoint, endPoint 속성: 가로 또는 다양한 방향으로 그라데이션을 적용하고 싶은 경우 사용
- startPoint와 endPoint는 방향을 의미: ex) 가로로 적용하고 싶은 경우에 (0, 0.5) -> (1, 0.5)로 지정

// 가로 그라데이션
let gradientLayer = CAGradientLayer()
gradientLayer.frame = myView.bounds
gradientLayer.colors = [UIColor.orange.cgColor, UIColor.red.cgColor, UIColor.black.cgColor]
gradientLayer.startPoint = CGPoint(x: 0, y: 0.5) // <- 추가
gradientLayer.endPoint = CGPoint(x: 1, y: 0.5) // <- 추가
myView.layer.addSublayer(gradientLayer)

// 대각선 그라데이션
gradientLayer.startPoint = CGPoint(x: 0, y: 0)
gradientLayer.endPoint = CGPoint(x: 1, y: 1)

텍스트에 그라데이션을 넣어서 텍스트 gradient fade out 처리 구현
- UIView의 layer.mask 속성: 텍스트에도 동일하게 CAGradientLayer()를 사용하면 되지만, 뷰가 아닌 글자에만 그라데이션을 입힐 경우 사용
- layer.mask속성을 사용하지 않을 경우 아래처럼 view자체에 그라데이션이 덮어지는 현상 발생
let gradientLayer = CAGradientLayer()
gradientLayer.frame = myLabel.bounds
gradientLayer.colors = [UIColor.orange.cgColor, UIColor.red.cgColor, UIColor.black.cgColor]
gradientLayer.startPoint = CGPoint(x: 0, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1, y: 0.5)
myLabel.layer.addSublayer(gradientLayer)

- layer.mask속성을 사용하여 gradient fade out 적용
extension UILabel {
func fadeOutTail() {
let gradientLayer = CAGradientLayer()
gradientLayer.frame = bounds
gradientLayer.colors = [textColor.cgColor, UIColor.clear.cgColor]
gradientLayer.startPoint = CGPoint(x: 0.95, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
layer.mask = gradientLayer
}
}

- 텍스트에서는 black, clear 컬러를 제외한 다른 컬러에서는 그라데이션이 적용이 안되는 경우가 존재하므로, image를 만들어 color로 표현해 주어야 가능
- UIGraphicsBeginImageContextOptions 관련 개념 참고: ios-development.tistory.com/manage/posts/
func gradientLayer(bounds : CGRect) -> CAGradientLayer{
let gradient = CAGradientLayer()
gradient.frame = bounds
gradient.colors = [UIColor.orange.cgColor, UIColor.red.cgColor]
gradient.startPoint = CGPoint(x: 0.0, y: 0.5)
gradient.endPoint = CGPoint(x: 1.0, y: 0.5)
return gradient
}
func gradientColor(gradientLayer :CAGradientLayer) -> UIColor? {
UIGraphicsBeginImageContextWithOptions(gradientLayer.bounds.size, false, 0.0)
gradientLayer.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return UIColor(patternImage: image!)
}
let gradient = gradientLayer(bounds: myLabel.bounds)
myLabel.textColor = gradientColor(gradientLayer: gradient)

* 참고
- developer.apple.com/documentation/quartzcore/cagradientlayer