SwiftUI를 위한 Swift 5.1 기능
Opaque 리턴 타입
- SwiftUI에서
some
이라는 키워드가 눈에 띄었다. some
은 opaque 리턴 타입을 선언할 수 있게 해준다.- 즉,
some
을 통해 generic한 protocol도 리턴 타입으로 사용될 수 있다. - 가장 대표적으로,
some
은 SwiftUI의 body에서 사용된다.
struct ContentView: View {
var body: some View {
Text("Hello, world!")
}
}
some
이 없었다면, 아래와 같이 특정 View 타입을 지정해주거나
struct ContentView: View {
var body: Text {
Text("Hello, world!")
}
}
- AnyView를 사용해 타입을 지워야한다.
- 그러면 리턴할때마다 타입을 다음과 같이 지워야한다.
struct ContentView: View {
var body: AnyView {
AnyView(Text("Hello, world!"))
}
}
return 생략
- 단일 표현 함수는 return 키워드를 생략할 수 있다.
- 아래의 두 코드는 동일하게 작동한다.
struct ContentView: View {
var body: some View {
return Text("Hello, world!")
}
}
struct ContentView: View {
var body: some View {
Text("Hello, world!")
}
}
Function builders
23년 10월 기준 Function Builder는 ResultBuilder로 대체 됨.
some
키워드나 return 키워드 생략은 View에 대해 이해가 가능하게 해준다.- 하지만 여전히
VStack
,HStack
,Group
에 대한 이해는 불가능하다. - 아래와 같은 코드가 return이나 추가 문법 없이 어떻게 하나로 묶이는지 설명이 안된다.
struct HeaderView: View {
let image: UIImage
let title: String
var body: some View {
VStack {
Image(uiImage: image)
Text(title)
}
}
}
- function builder(현재는 @resultBuilder)가 이를 설명해준다.
- 이에 대한 자세한 설명은, 애플 공식 문서를 참고하자.
Property wrappers
- property wrapper는 말그대로 property 값이 자동으로 wrap되는 기능이다.
- SwiftUI에서는 이를 통해, bindable property들을 쉽게 정의할수 있게 도와준다.
@State
가 하나의 예시가 될 수 있다.
struct Setting: View {
@State var save: Bool
@State var enable: Bool
var body: some View {
return VStack {
Toggle(isOn: $save) {
Text("Save")
}
Toggle(isOn: $enable) {
Text("Enable")
}
}
}
}
- 위 예시와 같이
@State
는 property의 값을 State 타입으로 wrap 해준다. - 여기서 property wrapper이 없었다면 아래와 같이 작성해야 할 것이다.
struct Setting: View {
var save: State<Bool>
var enable: State<Bool>
var body: some View {
return VStack {
Toggle(isOn: save.binding) {
Text("Save")
}
Toggle(isOn: enable.binding) {
Text("Enable")
}
}
}
}
- SwiftUI의 State 구조체는 다음과 같이 단순화 시킬 수 있기 때문이다.
@propertyWrapper
struct State<Value> {
init(initialValue: Value) {
...
}
var wrappedValue: Value {
get { ... }
set { ... }
}
}