[Swift] 협업을 위한 디자인 시스템 만들기 ft.열거형

David·2023년 8월 26일
0
post-thumbnail

협업을 하다 보니, 같은 이미지를 Assets에 또 추가하거나 피그마에는 같은 폰트의 크기와 행간인데 미세하게 다르다거나.. 하는 경우들이 있더라고요.

아티클을 봤는데 현재 진행중인 사이드 프로젝트에 적용할 수 있을 것 같아서 적용해 보았습니다.

컬러

앱에서 사용되는 컬러를 아래와 같이 열거형으로 정리했습니다.

enum DesignSystemColor {
    case lightGreen
    case green
    case signature
    case red
    case gray
    case white
}

extension DesignSystemColor {
    var value: UIColor {
        switch self {
        case .lightGreen:
            return UIColor(hex: "11D796")
        case .green:
            return UIColor(hex: "009967")
        case .signature:
            return UIColor(hex: "475FFD")
        case .red:
            return UIColor(hex: "FF2323")
        case .gray:
            return UIColor(hex: "D9D9D9")
        case .white:
            return UIColor(hex: "FFFFFF")
        }
    }
}

또한, 컬러는 하단과 같이 hex 코드로 적용할 수 있게 하였습니다.

extension UIColor {
    
    convenience init(hex: String) {
        
        let scanner = Scanner(string: hex)
        _ = scanner.scanString("#")
        
        var rgb: UInt64 = 0
        scanner.scanHexInt64(&rgb)
        
        let r = Double((rgb >> 16) & 0xFF) / 255.0
        let g = Double((rgb >>  8) & 0xFF) / 255.0
        let b = Double((rgb >>  0) & 0xFF) / 255.0
        
        self.init(red: r, green: g, blue: b, alpha: 1.0)
    }
}

폰트

폰트는 텍스트 굵기와 크기, 행간 순으로 네이밍을 하였으며, 폰트 또한 따로 익스텐션을 적용하여 조금 더 사용이 편하게 하였습니다.

enum DesignSystemFont {
    case bold22L100
    case semibold20L140
    case semibold18L100
    case medium16L100
    case medium16L150
    case semibold14L150
    case regular14L150
    case medium12L150
    
}

extension DesignSystemFont {
    var value: UIFont {
        switch self {
        case .bold22L100:
            return UIFont.pretendard(.bold, size: 22)
        case .semibold20L140:
            return UIFont.pretendard(.semiBold, size: 20)
        case .semibold18L100:
            return UIFont.pretendard(.semiBold, size: 18)
        case .medium16L100:
            return UIFont.pretendard(.medium, size: 16)
        case .medium16L150:
            return UIFont.pretendard(.medium, size: 16)
        case .semibold14L150:
            return UIFont.pretendard(.semiBold, size: 14)
        case .regular14L150:
            return UIFont.pretendard(.regular, size: 14)
        case .medium12L150:
            return UIFont.pretendard(.regular, size: 14)
        }
    }
    
    var lineHeightMultiple: CGFloat {
        switch self {
        case .bold22L100:
            return 0.84
        case .semibold20L140:
            return 1.17
        case .semibold18L100:
            return 0.84
        case .medium16L100:
            return 0.84
        case .medium16L150:
            return 1.26
        case .semibold14L150:
            return 1.26
        case .regular14L150:
            return 1.26
        case .medium12L150:
            return 1.26
        }
    }
    
}
extension UIFont {
    
    enum Pretendard {
        
        case bold
        case extraBold
        case medium
        case semiBold
        case regular
        
        var value: String {
            switch self {
            case .bold:
                return "Pretendard-Bold"
            case .medium:
                return "Pretendard-Medium"
            case .semiBold:
                return "Pretendard-SemiBold"
            case .extraBold:
                return "Pretendard-ExtraBold"
            case .regular:
                return "Pretendard-Regular"
            }
        }
    }
    
    static func pretendard(_ type: Pretendard, size: CGFloat) -> UIFont {
        return UIFont(name: type.value, size: size) ?? UIFont.systemFont(ofSize: size)
    }
}

아이콘

enum DesignSystemIcon {
    case setting
    case emptyAlarm
    case alarm
    case filter
    case verticalEllipsis
    case emptyCircleCheckmark
    case circleCheckmark
    case emptySquareCheckmark
    case squareCheckmark
    
}

extension DesignSystemIcon {
    var imageName: String {
        switch self {
        case .setting:
            return "setting"
        case .emptyAlarm:
            return "emptyAlarm"
        case .alarm:
            return "alarm"
        case .filter:
            return "filter"
        case .verticalEllipsis:
            return "verticalEllipsis"
        case .emptyCircleCheckmark:
            return "emptyCircleCheckmark"
        case .circleCheckmark:
            return "circleCheckmark"
        case .emptySquareCheckmark:
            return "emptySquareCheckmark"
        case .squareCheckmark:
            return "squareCheckmark"
        }
    }
}

폰트와 컬러, 아이콘의 사용법은 하단과 같습니다.

private let testLabel = UILabel().then{
        $0.font = DesignSystemFont.bold22L100.value
        $0.textColor = DesignSystemColor.signature.value
    }
    
    private let testView = UIImageView().then {
        $0.image = UIImage(named: DesignSystemIcon.circleCheckmark.imageName)
    }

0개의 댓글