관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 그라데이션 (gradient, gradation, CAGradientLayer) 주는 방법 본문

iOS 응용 (swift)

[iOS - swift] 그라데이션 (gradient, gradation, CAGradientLayer) 주는 방법

jake-kim 2024. 7. 22. 01:33

그라데이션 주는 방법

  • Swift에서 그라데이션을 주려면 뷰의 layer에 CAGradientLayer을 추가하여 적용 필요
  • 때문에 그라데이션 효과를 주는 CAGradientLayer와 이것을 UIView가 필요
let gradationView = UIView()
let gradientLayer = CAGradientLayer()
gradientView.layer.addSublayer(gradientLayer)
  • 또 layoutSubviews와 같은 화면의 크기가 결정되었을때 호출되는 시점에 gradientLayer의 frame 업데이트가 필요
override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    gradientLayer.frame = gradientView.bounds
}

예시) 화면 상단 그라데이션 적용

  • tableView같은 데이터가 있고, 스크롤 할 때 tableView 상단 라인에 그라데이션을 주어 자연스럽게 보이도록하는 효과

  • gradientView, gradationLayer 준비
    • gradientView는 터치 이벤트가 먹지 않아야 하므로 isUserInteractionEnabled를 false로 설정
    • gradientLayer에서는 그라데이션 색상을 color 프로퍼티에 설정
    • 그라데이션 시작 지점, 마지막 지점은 화면 좌표 활용 (0,0)은 화면 좌측 상단, (1,1)은 화면 우측 하단이므로 startPoint는 (0.5, 0), endPoint는 (0.5, 1)로 설정
class ViewController: UIViewController {
    private let topGradientView = {
        let v = UIView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.isUserInteractionEnabled = false
        return v
    }()
    private lazy var topGradientLayer = {
        let layer = CAGradientLayer()
        let color = UIColor.white
        layer.colors = [
            color,
            color.withAlphaComponent(0.4),
            color.withAlphaComponent(0.7),
            color.withAlphaComponent(0.0),
        ].map(\.cgColor)
        layer.startPoint = CGPoint(x: 0.5, y: 0)
        layer.endPoint = CGPoint(x: 0.5, y: 1)
        return layer
    }()
...
}
  • 그라데이션 배치
    • gradientView의 위치와 크기만 먼저 설정하고, gradientLayer는 따로 layoutSubviews()시점에 frame만 변경해주기 
private func setupTopGradient() {
    guard !view.subviews.contains(topGradientView) else { return }
    view.addSubview(topGradientView)
    view.bringSubviewToFront(topGradientView)
    topGradientView.layer.addSublayer(topGradientLayer)
    
    NSLayoutConstraint.activate([
        topGradientView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
        topGradientView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
        topGradientView.topAnchor.constraint(equalTo: tableView.topAnchor),
        topGradientView.heightAnchor.constraint(equalToConstant: 100)
    ])
}
  • gradientView만 autolayout으로 설정된 상태이며, gradationLayer는 프레임을 직접 지정해주어야함
    • 뷰 크기가 결정된 상태에서 호출되는 layoutSubviews() 시점에 gradientLayer의 프레임을 설정
override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    topGradientLayer.frame = topGradientView.bounds
}

(완성)

* 전체 코드: https://github.com/JK0369/ExGradation

Comments