• Review
    • attributedString
    • map
  • Gradient layer
  • Git
    • HEAD detached from commit
  • remove animations

Review Previous Episodes


let attributedText = NSMutableAttributedString(string: name, attributes: [.font: UIFont.systemFont(ofSize: 32, weight: .heavy)])
        attributedText.append(NSAttributedString(string: "  \(age)", attributes: [.font: UIFont.systemFont(ofSize: 24, weight: .bold)]))
        attributedText.append(NSAttributedString(string: "\n\(profession)", attributes: [.font: UIFont.systemFont(ofSize: 20, weight: .bold)]))


A mutable string object that also contains attributes (such as visual style, hyperlinks, or accessibility data) associated with various portions of its text content.


Adds the characters and attributes of a given attributed string to the end of the receiver.


let cardViewModels: [CardViewModel] = {
        let producers = [
            User(name: "Kelly", age: 23, profession: "Music DJ", imageName: "lady5c"),
            User(name: "Jane", age: 19, profession: "Teacher", imageName: "lady4c"),
            Advertiser(title: "Final Announcement", brandName: "ECONOVATION", posterPhotoName: "final_poster"),
            User(name: "Jane", age: 19, profession: "Teacher", imageName: "lady4c")
        ] as [ProducesCardViewModel]
        let viewModels = producers.map({return $0.toCardViewModel()})
        return viewModels

프로토콜 주의

user, advertiser들을 생성한 뒤에 모두 동일한 toCardViewModel 함수를 실행 시킬 것이므로

producers.map({return $0.toCardViewModel()}) 을 통해 모든 원소에 함수 적용 (layout extension에서 한번 사용한 스킬)

ep 10 : Gradient Layer and Animation Fix

In this quick lesson, we’ll look at how we can implement a nice subtle gradient inside the CardView objects we are presenting for the UI. This is done by adding a sublayer called a CAGradientLayer. You’ll then need to set up the correct colors, locations, and frame property to have it show up correctly.

Gradient layer

gradient layerlayersublayer로 추가해야한다.


The view’s Core Animation layer used for rendering.

let gradientLayer = CAGradientLayer()
gradientLayer.colors = [UIColor.clear.cgColor, UIColor.black.cgColor]
gradientLayer.locations = [0.5, 1.1]

layer 또한 frame을 설정해줘야한다.

gradientLayer.frame = self.frame 을 사용해 frame을 주려고 하면 적용되지 않는다.

CardView(frame: .zero)로 생성했기 때문에 frame은 사실 zero이다.

    fileprivate func setupDummyCards() {
        cardViewModels.forEach { (cardVM) in
            let cardView = CardView(frame: .zero)
            cardView.cardViewModel = cardVM

그래서 아래 함수를 오버라이드 하여 frame을 적용시킨다.


관련 설명 블로그

**layer 생명주기 **중 하나로 이 함수 안에서는 cardView.fillSuperview()가 이미 적용된 상태의 frame을 반영한다.

현재 CardView이기 때문에 self : CardView

    override func layoutSubviews() {
        // in here you know what your CardView frame will be
        gradientLayer.frame = self.frame

이를 적용시키기 위해 gradientLayer는 전역 상수로 만들어준다.

refator: CardView class 내부에서 설정해줬던 프론트 변경사항들은 모두 제거해서 코드를 깔끔하게 정리한다.

Git issue: HEAD detached from commit

What’s a “detached HEAD”


remove animations

오류가 많아지기 때문에 animation을 제거해준다.

@objc fileprivate func handlePan(gesture: UIPanGestureRecognizer) {
        switch gesture.state {
        case .began:
            superview?.subviews.forEach({ (subview) in
        case .changed:
        case .ended:

.began state를 추가해 클릭하자마자 애니메이션을 제거해준다.

태그: ,