본문 바로가기

iOS

[iOS] Custom Color 생성과 관리는 어떤 방식이 효율적일까요?

if kakao의 세션 중 하나인 "다크모드로 알아보는 카카오페이지의 iOS 업데이트"를 보다가 다음에 적용해보고 싶은 방법에 대해서 작성한 글입니다.

 

안녕하세요! 오늘은 프로젝트를 진행하면서 UIColor를 어떤식으로 생성하고 관리해야 효율적인지에 대해 알아보겠습니다🤔🤔🤔

 

Xcode에서는 뷰나 구성요소의 색깔을 주는 방법은 크게 두가지로 나눌 수 있습니다.

1. IBOutlet을 연결한 후 코드로 색상 주기

2. Interface Builder에서 Storyboard나 Xib파일에서 직접 원하는 색상 주기

이미 생성되어 있는 색깔을 사용할 땐 위와 같이 간단하게 관리할 수 있습니다. 

(하지만, 이것도 관리해주어야하는 인터페이스가 너무 많아질 경우 귀찮아질 수 있습니다ㅎㅎ 이럴 때 어떻게 해야할지는 아직 생각해보지 않았네요. 다 일일이 바꿔줘야할까..?)

 

위와 같이 xcode에서 이미 제공해주는 Color가 아닌 직접 생성해서 사용하는 Custom Color를 생성하고 관리하는 방법을 적어보았습니다.

 

Extension파일을 만들고 IBOutlet으로 관리하기

Interface Builder에서 IBOutlet을 생성하여 코드로 원하는 색상을 부여하는 방법을 주로 사용했습니다. 아래와 같이 색상을 extension으로 작성한 후에 코드로 부여하는 방식입니다.

extension UIColor {
    enum Button {
        static let text: UIColor = { UIColor(hexInt: 0x34711eb) }()
        static let transparendGray: UIColor = { UIColor(hexInt: 0x1900000) }()
    }
    
    enum Background {
        static let `default` = { UIColor(hexInt: 0x9c9c9c) }()
        static let gray = { UIColor(hexInt: 0xc6c6c6) }()
    }
    
}
let myButton = UIButton()
myButton.titleLabel?.textColor = UIColor.Button.text

// iOS13 업데이트 이후 다크모드 적용할 때 
let buttonBlue = UIColor { (traitCollection) -> UIColor in
            if traitCollection.userInterfaceStyle == .dark {
                return UIColor.Button.text
            } else {
                UIColor(hexInt: 0xa2a2a2)
            }
}
        
let button = UIButton()
button.titleLabel?.textColor = buttonBlue

이 방식은 평상시 간단한 개발을 하며 가장 많이 사용하는 방식이지만 생성한 Custom Color를 인터페이스 빌더에서 사용하지 못한다는 단점을 가지고 있습니다. 그래서 개발이 커지게 된다면 변경해야하는 인터페이스뷰가 많아지는 불편함과 색상만을 위해 코드를 작성해야하는 아쉬움이 있습니다.

 

Asset파일로 관리하기

Asset파일에서 Color Set을 생성하여 light모드와 dark모드일 때의 색상을 정해주는 방식입니다. 이렇게 Color set을 생성하게 된다면 Interface builder에서도 색상을 부여할 수 있고, 코드로도 접근이 가능하게 됩니다! 

iOS 13업데이트 이후 systemColor라는 개념이 새롭게 나오게 되었습니다. system Color는 light와 dark모드 일떄의 두가지 색상을 세트로 가지고 있어 위와 같이 생성해주어야 합니다. iOS12이전에서 system Color를 사용하게 될 경우, 자동으로 light모드일 떄의 색상을 보여줍니다.

위와 같이 Interface builder에서도 색깔을 설정할 수 있고, 또는 아래와 같이 코드로 설정할 수도 있습니다.

@IBOutlet weak var myView: UIView!
myView.backgroundColor = UIColor.init(named: "MyColor")

Asset파일에서 color set을 만들어 관리해줄 경우, 코드로 색상을 만들었을 때 Interface Builder에서는 사용이 불가능하다는 점을 보완할 수 있습니다!! 하지만 여기서도 아쉬운 점이 있었는데, 그것은 코드로 작성할 떄 String타입으로 직접 글로 작성해야 하므로 오타가 나면 빌드하기전까지는 오류를 잡아내지 못한다는 점이었습니다. 또한  String은 제대로 작성했으나 Asset에 color가 누락이 되었을 때 바로 인지가 불가능하다는 점도 있었습니다. 

 

이 불편함을 해결해주는 것이 SwiftGen 입니다! SwiftGen은 build시에 코드롤 작성해주어 string으로 작성되어 오타를 찾지 못하게 될 걱정을 덜어줍니다. SwiftGen을 도입함으로써 Color자원은 한 곳(Asset.xcassets)에서 관리가 가능해지고, 코드와 인터페이스 빌더에서 Color Name을 이용해서 사용이 가능하게 되었습니다!!! 

 

결론

프로젝트를 진행하면서 Color를 어떤 식으로 생성하고 관리해야 일을 더 적게할까라는 고민을 if kakao 세션영상을 통해 조금은 덜 수 있었습니다. 이젠 저도 거의 모든 앱을 다크모드로 이용하기 때문에 다크모드의 앱을 만들경우에도 위와 같은 방식으로 관리할 수 있으니 굉장히 유용한 방법이라고 생각되네요😄 개발자마다 모두 다 다른 방식을 사용하겠지만 저는 위의 방법이 불편해진다면 다시 고민해봐야겠네요 ㅎㅎ