Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- Xcode
- Protocol
- ios
- SWIFT
- map
- 클린 코드
- tableView
- 리펙터링
- 리펙토링
- clean architecture
- Observable
- Human interface guide
- collectionview
- uiscrollview
- uitableview
- rxswift
- UICollectionView
- HIG
- 스위프트
- MVVM
- swift documentation
- Clean Code
- UITextView
- swiftUI
- combine
- 애니메이션
- Refactoring
- RxCocoa
- ribs
- 리팩토링
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] Builder 패턴 사용 방법 (공통 컴포넌트 수정, 추가 쉽게하기) 본문
Builder 패턴이란?
- Builder 패턴은 객체를 생성하는 것을 추상화하여, 이 객체를 사용하는쪽에서 Builder라는 별도의 컴포넌트를 사용하여 단계적으로 필요한 옵션을 set 하면서 인스턴스를 만드는 방식
- 사용하는쪽에서 필요한 옵션을 set하고난 후 인스턴스를 얻을수 있어서, 여러곳에서 옵션을 유연하게 바꾸며 사용하기 쉽고 사용하는쪽에서 최초에 인스턴스를 만들때만 내부 값들을 변경하므로, 인스턴스가 만들어진 후에는 외부에서 바꾸어주는 상태가 없어서 새로운 기능에 대해서도 수정이나 추가가 용이
- 팝업과 같은 공통 컴포넌트에 builder 패턴을 적용하면 사용하는쪽에서 필요한 옵션을 set하면서 여러곳에서 사용하기가 용이
팝업에 Builder 패턴 사용해보기
* 예제 starter 코드(아래에서 위로 올라오는 커스텀 팝업): https://ios-development.tistory.com/1295
- 팝업 형태
- 문제점: label의 색상, button의 색상, 문구 등 사용하는쪽에서 쉽게 변경해서 쓸 수 있기가 어려움
- Builder패턴을 통해 리펙토링 해보기
final class CustomPopupViewController: DimmedViewController {
private let containerView: UIView = {
let view = UIView()
view.backgroundColor = .white
return view
}()
private let stackView: UIStackView = {
let view = UIStackView()
view.axis = .vertical
view.spacing = 12
view.backgroundColor = .white
return view
}()
private let label: UILabel = {
let label = UILabel()
label.textColor = .black
label.text = "iOS 앱 개발 알아가기 jake"
return label
}()
private let closeButton: UIButton = {
let button = UIButton()
button.setTitle("닫기", for: .normal)
button.setTitleColor(.systemBlue, for: .normal)
button.setTitleColor(.blue, for: .highlighted)
button.addTarget(self, action: #selector(close), for: .touchUpInside)
return button
}()
override init() {
super.init()
setUp()
}
required init?(coder: NSCoder) {
fatalError()
}
private func setUp() {
view.addSubview(containerView)
containerView.addSubview(stackView)
stackView.addArrangedSubview(label)
stackView.addArrangedSubview(closeButton)
containerView.snp.makeConstraints {
$0.leading.trailing.equalToSuperview().inset(20)
$0.centerY.equalToSuperview()
}
stackView.snp.makeConstraints {
$0.center.equalToSuperview()
$0.leading.top.greaterThanOrEqualToSuperview()
$0.bottom.trailing.lessThanOrEqualToSuperview()
}
}
@objc private func close() {
dismiss(animated: true)
}
}
- Builder 생성
- Builder를 만들기 전에 CustomPopupViewController에서 값을 입력받으면 UI를 변경하는 computed property 선언
// CustomPopupViewController.swift
var labelText: String? {
get { label.text }
set { label.text = newValue }
}
var labelColor: UIColor {
get { label.textColor }
set { label.textColor = newValue }
}
var buttonText: String? {
get { label.text }
set { label.text = newValue }
}
var buttonNormalColor: UIColor? {
get { closeButton.titleColor(for: .normal) }
set { closeButton.setTitleColor(newValue, for: .normal) }
}
var buttonHighlightedColor: UIColor? {
get { closeButton.titleColor(for: .highlighted) }
set { closeButton.setTitleColor(newValue, for: .highlighted) }
}
- builder 구현
- set 메소드를 호출하면 자기 자신, Self를 리턴하여 사용하는쪽에서 *선언적으로 프로그래밍할 수 있도록 구현
- *선언적: 어떻게에 관한 내용을 감추고 무엇을 하는것에 초첨을 두는 것
class CustomPopupBuilder {
private var labelText = "iOS 앱 개발 알아가기 jake"
private var labelColor = UIColor.black
private var closeButtonText = "닫기"
private var closeButtonNormalColor = UIColor.systemBlue
private var closeButtonHighlightedColor = UIColor.blue
func set(labelText: String) -> Self {
self.labelText = labelText
return self
}
func set(labelColor: UIColor) -> Self {
self.labelColor = labelColor
return self
}
func set(buttonText: String) -> Self {
self.closeButtonText = buttonText
return self
}
func set(buttonNormalColor: UIColor) -> Self {
self.closeButtonNormalColor = buttonNormalColor
return self
}
func set(buttonHighlightedColor: UIColor) -> Self {
self.closeButtonHighlightedColor = buttonHighlightedColor
return self
}
func build() -> CustomPopupViewController {
let vc = CustomPopupViewController()
vc.labelText = labelText
vc.labelColor = labelColor
vc.buttonText = closeButtonText
vc.buttonNormalColor = closeButtonNormalColor
vc.buttonHighlightedColor = closeButtonHighlightedColor
return vc
}
}
- 사용하는쪽
- 버튼을 탭 했을때 빌더를 통해서 팝업을 만들고 사용
// ViewController.swift
@objc private func tap() {
let popupVC = CustomPopupBuilder()
.set(labelText: "cutom label text")
.set(buttonNormalColor: .orange)
.build()
present(popupVC, animated: true)
}
- 만약 CustomPopupViewController의 containerView.background 색상을 변경하고 싶은 경우, CustomPopupViewController에 아래 코드를 추가
// CustomPopupViewController.swift
var contentBackgroundColor: UIColor? {
get { containerView.backgroundColor }
set { containerView.backgroundColor = newValue }
}
CustomPopupBuilder.swift
class CustomPopupBuilder {
private var contentBackgroundColor = UIColor.white
...
func set(contentBackgroundColor: UIColor) -> Self {
self.contentBackgroundColor = contentBackgroundColor
return self
}
...
}
// ViewController.swift
let popupVC = CustomPopupBuilder()
.set(contentBackgroundColor: .brown) // <-
.set(labelText: "cutom label text")
.set(buttonNormalColor: .orange)
.build()
present(popupVC, animated: true)
(완성)
* 전체코드: https://github.com/JK0369/ExBuilder
* 참고
'iOS 응용 (swift)' 카테고리의 다른 글
Comments