수업시간에 배운 ViewModifier를 어떻게 쓸 수 있을지에 대해 고찰을 해봤다.
모바일 개발은 처음 하는 사람들은 나처럼 위의 개념에 대해 생소한 사람들이 많을 것이다.
그래서 수업시간에 우리 팀에서 만든 계산기 어플을 이용해서 응용하는 방법을 소개하고자 한다!
정확하진 않지만! 나는 쉽게 이해하기 위해 다음과 같이 이해했다.
ViewModifier는 CSS 파일과 같은 기능을 한다.
(수정자, 속성을 하나의 묶음으로 만든 것)
수업시간에 계산기 어플을 만드는데, ViewModifier와 하위뷰를 이용하여 문서를 구조화하고 가독성이 좋은 코드로 편집해보기로 했다!
계산기 코드 문서의 구조는 위와 같다.
하지만 위에 보는 것처럼 구현해야 할 버튼이 무척 많고, 계산기 코드 문서의 대부분을 차지하는 것이 버튼 UI이다.
일단 이 계산기는 수업 중 우리 조에서 페어프로그래밍처럼 작성이 되어있다.
따라서 현재, 페이지 내 코드의 구조화가 전혀 이루어져있지 않고 일단 하드코딩으로 시작해서 만든 작품이다!
버튼에 대한 코드를 살펴보면,
Button{
if (flag == true) {
totalNumber = "0"
flag = false
}
if totalNumber == "0"{
totalNumber = "4"
}else{
totalNumber += "4"
}
} label: {
Text("4")
}
.frame(width: 80, height: 80)
.foregroundColor(.white)
.font(.system(size: 33))
.background(Color("BackgroundSpaceColor"))
Button{
if (flag == true) {
totalNumber = "0"
flag = false
}
if totalNumber == "0"{
totalNumber = "5"
}else{
totalNumber += "5"
}
} label: {
Text("5")
}
.frame(width: 80, height: 80)
.foregroundColor(.white)
.font(.system(size: 33))
.background(Color("BackgroundSpaceColor"))
버튼 두개의 대한 것만 일단, 작성한 것이다... 딱봐도 알겠지만 버튼 두개만으로도 이렇게 코드가 길어지는 데 19개의 버튼을 이처럼 구성하면 코드가 엄청 길어진다. 따라서 이를 구조화해보기로 하자!
ViewModifier 선언
Button 컴포넌트 수정자를 통합해주는 Viewmodifier를 선언한다.
이를 선언할 때에는 컴포넌트 뒤에 붙는 속성에 대한 코드만 보면 되겠다.
.frame(width: 80, height: 80)
.foregroundColor(.white)
.font(.system(size: 33))
.background(Color("BackgroundSpaceColor"))
계산기 페이지를 보면 버튼의 종류는 다음으로 나뉜다.
- 숫자 버튼
- 연산자 버튼
- 특수기능 버튼
따라서 세 종류의 버튼을 보면, 차이점은 배경색이다. 그럼 다음처럼 ViewModifier를 선언할 수 있겠다.
struct ButtonModifierView: ViewModifier {
let color: String
init(color: String){
self.color = color
}
func body(content: Content) -> some View {
content
.frame(width: 80, height: 80)
.foregroundColor(.white)
.font(.system(size: 33))
.background(Color(color))
}
}
* '0'버튼은 크기가 다른 버튼과 다르기 때문에 개별적으로 선언을 해줬다.
그럼 원래의 코드가 다음처럼 수정된다.
Button{
if (flag == true) {
totalNumber = "0"
flag = false
}
if totalNumber == "0"{
totalNumber = "4"
}else{
totalNumber += "4"
}
} label: {
Text("4")
}
.modifier(ButtonModifierView(color: "NumberButtonColor"))
Button{
if (flag == true) {
totalNumber = "0"
flag = false
}
if totalNumber == "0"{
totalNumber = "5"
}else{
totalNumber += "5"
}
} label: {
Text("5")
}
.modifier(ButtonModifierView(color: "NumberButtonColor"))
Button의 하위뷰 선언
이제 Button 컴포넌트를 한줄로 작성될 수 있도록 Button에 대한 하위뷰를 만들어보려고 한다!
하지만 이는 앞서 ViewModifier를 구현한 것 처럼 한 개의 하위뷰만 만들 수가 없다. 왜냐하면 버튼의 종류에 따라 버튼 기능에 대한 로직이 다르기때문이다. 따라서, 3가지의 하위뷰 - 숫자 버튼, 연산자 버튼, 특수기능 버튼을 만들기로 하자.
숫자 버튼의 하위뷰
struct NumberButton: View{
@Binding var totalNumber: String
@Binding var flag: Bool
let numberString: String
var body: some View{
Button{
if(flag == true){
totalNumber = "0"
flag = false
}
if totalNumber == "0"{
totalNumber = numberString
} else{
totalNumber += numberString
}
} label: {
Text(numberString)
}
.modifier(ButtonModifierView(color: "NumberButtonColor"))
}
}
위처럼 하위뷰를 선언해줬다. 여기서 Button 내의 로직에 대한 것은 중요하지 않다.
'어떻게' 하위뷰를 작성했는지가 중요하다.
Button 컴포넌트 하나가지고 하위뷰를 작성하는 것이 큰 차이가 있어?
라고 말씀하신다면 다음을 봐보라!
NumberButton(totalNumber: $totalNumber, flag: $flag, numberString: "4")
NumberButton(totalNumber: $totalNumber, flag: $flag, numberString: "5")
위 두줄이, 처음 소개한 코드와 같은 코드이다. 결국 content 뷰 내에 들어가게 되는 문장은 저 두줄이 된다.
문서의 가독성이 더욱 좋아지고 전체 문서의 코드가 엄청 줄어들게 되었다. 모르는 사람이 코드 문서를 해석할 때 소비되는 시간과 노력이 확연히 줄어들게 될 것이다!
하위뷰를 작성하기전에 먼저 확인해야할 사항은 '반복되는 구간'이다.
전체적인 흐름에서 반복되는 부분을 먼저 파악하고, 반복되지 않는 일부 부분은 ViewModifier, ViewBuilder, 하위뷰, 변수 등으로 대체해준다.
얻게된 효과
이렇게 얻게 된 결과는 위와 같다.
전체 소스코드 466줄에서 263줄로 약 200여줄의 불필요한 코드들이 하위뷰와 ViewModifier로 간소화 되었고, 버튼 종류별로 구분되어있어서 나중에 유지보수하는 데도 유용해지는 기대효과가 있다.
그리고 간단한 주석만 추가한다면 이 코드를 작성하지 않은 제 3자가 봐도 다음 내용을 쉽게 해석할 수 있다.
- 각 하위뷰가 무엇을 나타내는지
- 해당 변수는 무엇을 조정하는지
- 각 버튼마다 ViewModifier에 전달되는 요소는 무엇인지
코드 설계부터 ViewModifier를 적용하는게 어려울 수도 있다.
코드 설계부터 하위뷰를 종류별로 구분하고 구조화하는 것이 어려울 수도 있다.
그렇다면! 일단 작성해보고 보여지는 패턴들을 파악한 후에 구조화를 해보자!
'SwiftUI' 카테고리의 다른 글
SwiftUI Firebase Email Auth Login 구현하기 (0) | 2022.12.23 |
---|---|
SwiftUI Firebase Auth - Google Account 연동하기 (0) | 2022.12.23 |
SwiftUI Firebase Realtime Database CRUD 제대로 사용하기 (12) | 2022.12.08 |
ATS Policy에 의한 HTTP 통신 제약 (0) | 2022.11.28 |
SwiftUI 문서 구조화 해보기 - 초급 (0) | 2022.11.07 |