최근 사이드 프로젝트와 리팩토링을 진행하면서 느끼게 된 부분이 있어요.
앱 UI는 개발/업데이트/리팩토링을 하다보면, 바뀌는 경우가 많잖아요.
예를 들면, 내가 만든 앱의 한 개의 버튼이 디자인 통일성을 해친다는 사용자 피드백을 받았어요.
그러면 그 사용자 피드백을 토대로 버튼의 디자인을 살펴 볼 거에요.
오랜 회의 또는 고민을 거쳐 기존 버튼을 제거하고 새로운 버튼을 생성해야 한다는 결론이 나왔어요.
그런데, 기존의 버튼 코드는 VC에서 만들었네요?
거기다가 버튼 생성/치수 코드들이 전부 VC 전체에 분포해 있군요.(잘못 건드리면 빨간 줄 지옥을 볼 수도 있음...)
그래서 어떻게 하면 UI 를 더 효율적으로 교체할 수 있을까라는 고민을 했어요.
제가 생각한 방법은 UI의 타입만 지정하고, 외부에서 버튼 UI 를 만든 후에 그냥 VC에 주입하는 방식이에요.
아래의 예시 코드를 보여드릴게요.
타입만 선언한 버튼 변수를 생성합니다. 여기서 !를 사용한 이유는 이미 우리는 버튼이 있다는 것을 알고 있기 때문에 사용했습니다.
var button: UIButton!
먼저, 직사각형 버튼을 사용하기 위해 외부에서 만들어 보겠습니다.
여기서 UI 구성을 다 해줍니다.
class RectangleButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
private func setup() {
translatesAutoresizingMaskIntoConstraints = false
backgroundColor = .systemOrange
tintColor = .white
layer.cornerRadius = 10
layer.masksToBounds = true
setTitle("Test Button 1", for: .normal)
titleLabel?.font = .systemFont(ofSize: 20, weight: .bold)
titleLabel?.adjustsFontSizeToFitWidth = true
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
그 이후, VC로 돌아와 액션동작과 치수를 조정합니다. 전 여기서, 버튼을 주입하겠습니다.(굳이 아래코드에서 주입할 필요는 없습니다.)
버튼을 등록/치수/액션 동작을 설정합니다.
private func setup() {
/// 여기서 사용할 버튼 모듈을 button 변수에 주입
button = RectangleButton(frame: .init(x: 0, y: 0, width: 160, height: 80)) // 직사각형 버튼
view.addSubview(button)
/// 버튼 치수 조정
button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
button.widthAnchor.constraint(equalToConstant: button.frame.width).isActive = true
button.heightAnchor.constraint(equalToConstant: button.frame.height).isActive = true
button.addTarget(self, action: #selector(didTapButton), for: .touchUpInside)
}
그리고 실행을 해보면!!
이렇게 버튼이 생성 되었습니다.
그려면, 이번엔 원형 버튼을 만들어보겠습니다.
직사각형 버튼과 동일한 형식이지만, setup 함수만 다르게 만듭니다.
private func setup() {
translatesAutoresizingMaskIntoConstraints = false
backgroundColor = .systemMint
tintColor = .black
layer.cornerRadius = frame.width / 2
layer.masksToBounds = true
setTitle("Test Button 2", for: .normal)
titleLabel?.font = .systemFont(ofSize: 20, weight: .bold)
titleLabel?.adjustsFontSizeToFitWidth = true
}
그 이후, VC로 돌아와서 setup 함수 안 버튼 주입 부분을 바꿔줍니다.
// button = RectangleButton(frame: .init(x: 0, y: 0, width: 160, height: 80)) // 직사각형 버튼
button = CircleButton(frame: .init(x: 0, y: 0, width: 160, height: 160)) // 원형 버튼
그리고 실행을 해보면!!
원형 버튼으로 잘 바뀐 것을 볼 수 있습니다.
이 방법을 응용한다면 VC 도 바꿔끼울 수 있을 거 같네요. 이 방법은 좀 더 공부해보고 다시 글을 쓰는 것? 으로 해보겠습니다.