적당한 고통은 희열이다

- 댄 브라운 '다빈치 코드' 중에서

초보 iOS 개발자의 일상/개발 업무

[Swift iOS] Set gradient 그라디언트 뷰 적용하는 법 (+ 안뜰때!!)

hongssup_ 2023. 6. 28. 12:36
반응형

 

 

 

그라디언트 뷰를 따로 만들어서 사용하는 방법

class GradientView: UIView {
    private let gradientLayer = CAGradientLayer()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setGradientLayer()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setGradientLayer() {
        gradientLayer.frame = bounds
        gradientLayer.colors = [UIColor.blue.cgColor, UIColor.red.cgColor]
        gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0)
        gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)
        layer.addSublayer(gradientLayer)
    }
}
class MyCollectionViewCell: UICollectionViewCell {
    private let gradientView = GradientView()
    ...
}

 

셀 내에서 그라디언트 뷰 컴포넌트를 직접 만들어서 사용하는 방법

layoutSublayers 혹은 layoutSubviews() 를 사용하여 자동으로 뷰를 업데이트 시켜줄 수 있다.

class MyCollectionViewCell: UICollectionViewCell {
    private let gradientView = UIView()
    private var gradientLayer: CAGradientLayer!
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setGradientLayer()
    }
    
    override func layoutSublayers(of layer: CALayer) {
        super.layoutSublayers(of: layer)
        gradientLayer.frame = gradientView.bounds
    }
    
    private func setGradientLayer() {
        gradientLayer = CAGradientLayer()
        gradientLayer.frame = gradientView.bounds
        gradientLayer.colors = [UIColor(red: 78, green: 175, blue: 168).cgColor, MacaColors.turquoise600.cgColor]
        gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.2)
        gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.8)
        gradientView.layer.addSublayer(gradientLayer)
    }
}

 

 

근데 이렇게 해줘도 왜 그라디언트 뷰가 안먹는 것이야!!!

 

홈 화면의 테이블뷰 셀 내에 컬렉션 뷰를 넣었더니, 뷰 그리는 시점이 잘 안맞는건지 뭔지 그라디언트 뷰를 적용해도 잘 먹지 않는 문제가 발생했다. 

보통은 그라디언트 뷰 적용할 때, init() 에서 세팅을 해준 후, layoutSubviews() 내에서 frame 만 다시 잡아주는 형식으로 적용을 하는 것 같은데

아무리 해도 안댐,, 

이런 저런 삽질을 하다가 결국 setGradientLayer() 함수 내에 프레임을 잡아 주기 전, layoutIfNeeded() 를 써서 강제로 업데이트 시켜주는 방식으로 구현을 했다. 

 

레이아웃을 강제로 즉시 업데이트해주는 layoutIfNeeded() 는 남용하면 성능에 부담을 줄 수도 있지만, 

init() 할 때 설정을 해주면, 셀이 처음 초기화 될 때만 호출이 되고 셀이 재사용될 때에는 따로 호출을 반복하지 않기 때문에

이렇게 해주면 성능에도 문제 없이 작동이 되는 같다! 😊

 

 

 

https://stackoverflow.com/questions/10818319/when-do-i-need-to-call-setneedsdisplay-in-ios

https://developer.apple.com/tutorials/app-dev-training/creating-a-gradient-background

https://zeddios.tistory.com/359

728x90
반응형