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
- 리펙토링
- RxCocoa
- MVVM
- HIG
- ribs
- UICollectionView
- UITextView
- Human interface guide
- Observable
- Xcode
- uitableview
- swift documentation
- 클린 코드
- clean architecture
- rxswift
- Protocol
- 리펙터링
- ios
- Refactoring
- 리팩토링
- SWIFT
- swiftUI
- uiscrollview
- map
- combine
- 스위프트
- tableView
- Clean Code
- collectionview
- 애니메이션
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] 2. @resultBuilder 이해하기 - 응용하여 깔끔한 코드 만들기 본문
1. @resultBuilder 이해하기 - 만들어진 이유
2. @resultBuilder 이해하기 - 응용하여 깔끔한 코드 만들기
3. @resultBuilder 이해하기 - 선언형 UI 만들기 (Declarative UI)
@resultBuiler 개념 복습
- 이름이 result builder인 이유?
- 결과를 만들어주는 역할을 담당
- 결과를 만들어준다는 의미는 lazy var로 선언것처럼 코드 블록 내에서 여러 개의 값을 취합하여 return 키워드 없이 하나의 결과로 반환하는 것을 도와주는 기능
- 목적: 빌딩을 간소화하는 것
SwiftUI에서 @resultBuilder 사용
- result buildr의 기능: 여러 개의 값을 취합하여 return 키워드 없이 하나의 결과로 반환해주는 것
- 따로 function을 만들어서 분리할 필요 없이 SwiftUI에서 뷰를 선언형으로 만들기가 가능
ex) SwiftUI에서 VStack안에 여러개의 Text를 넣을 때 ForEach를 사용하는데 이를 따로 함수로 빼지 않고 바로 Text()를 ForEach안에 선언하여 사용이 가능
- 만약 @resultBuilder 속성을 사용할 수 없다면 ForEach문 자체를 하나의 함수로 빼고 이를 사용하는 쪽에서 호출하여 반환된 Text()뷰들을 사용
struct ContentView: View {
var body: some View {
ScrollView {
if #available(macOS 11.0, iOS 14.0, *) {
LazyVStack {
ForEach(1...1000, id: \.self) { value in
Text("Row \(value)")
}
}
} else {
VStack {
ForEach(1...1000, id: \.self) { value in
Text("Row \(value)")
}
}
}
}
}
}
@resultBuilder 응용
- @resultBuilder 키워드를 사용하고 Builder enum와 buildBlock(_) 함수를 정의
@resultBuilder
enum Builder<T> {
static func buildBlock(_ component: T) -> T { component }
}
- buildBlock에서 if-else도 사용할 수 있어야하므로, buildEither(first:)와 buildEither(second:)를 정의
@resultBuilder
enum Builder<T> {
static func buildBlock(_ component: T) -> T { component }
static func buildEither(first component: T) -> T { component }
static func buildEither(second component: T) -> T { component }
}
- 사용하는 쪽에서는 @Builder를 파라미터로 받아서 사용
// UIViewController.swift
let label = buildLabel {
if datas.count == 0 {
UILabel()
} else {
UILabel()
}
}
func buildLabel(@Builder<UILabel> _ closure: () -> UILabel) -> UILabel {
closure()
}
- buildLabel 함수를 더욱 추상화하여 일일이 이런 함수를 정의하지 않고 바로 쓸 수 있도록 전역으로 선언
func builder<T>(@Builder<T> _ closure: () -> T) -> T { closure() }
(사용하는쪽)
- return 키워드 없이 간소하게 사용 가능
let value2 = builder {
if datas.count == 0 {
1
} else {
2
}
}
let value3 = builder {
if datas.count == 0 {
UILabel()
} else {
UILabel()
}
}
* 전체 코드: https://github.com/JK0369/ExResultBuilder2
* 참고
'iOS 응용 (swift)' 카테고리의 다른 글
[iOS - swift] NSAttributedString와 NSMutableAttributedString개념 (애플이 굳이 두가지로 나눈 이유, #불변성) (0) | 2023.08.20 |
---|---|
[iOS - swift] 3. @resultBuilder 이해하기 - 선언형 UI 만들기 (Declarative UI, SwiftUI 같은 선언형 뷰 구현 방법) (0) | 2023.08.19 |
[iOS - swift] 1. @resultBuilder 이해하기 - 만들어진 이유 (0) | 2023.08.17 |
[iOS - swift] 화면전환 present, push 중첩하여 사용 이해하기 (2) | 2023.08.16 |
[iOS - swift] OptionSet 개념 (enum case + set) (0) | 2023.08.15 |
Comments