상세 컨텐츠

본문 제목

Day 23. Project 3, part 1

TIL/#100DaysOfSwiftUI

by box-jeon 2020. 3. 8. 22:13

본문

https://www.hackingwithswift.com/100/swiftui/23

 

100 Days of SwiftUI – Day 23 – Hacking with Swift

Project 3, part 1 Walt Disney once said, “there is no magic in magic, it’s all in the details.” The same is very much true of SwiftUI: it’s easy to look at it and think there’s all sorts of magic happening to make it work so efficiently, when really if you

www.hackingwithswift.com

갑작스럽게 분량이 많습니다. 프로젝트라고는 하지만 앱을 만드는 프로젝트는 아닌 모양입니다. View와 modifier에 관한 설명들이 이어집니다.

 

Why does SwiftUI use structs for views?

첫번재 이유는 일단 성능이었고, 두번째 이유로 상속으로 인한 불필요한 인터페이스를 들었습니다. 과연 struct가 class 보다 성능면에서 나은가, 오히려 복사가 더 많이 일어나니 반대 아닌가 싶었는데, Integer를 예로 들면서 10만개를 생성해도 전혀 부담없지 않느냐고 하니 그 말도 맞다는 생각이 듭니다. 또한, SwiftUI에서는 Color도 View, LinearGradient도 View, property도 각각 필요한 것만 들고 있는 반면에, UIView는 상속하기만 하면 200여개의 property가 함께 딸려온다는 거죠.

 

Why modifier order matters

Modifier가 호출되면 SwiftUI는 제네릭을 이용해 modifier를 적용한 ModifiedContent라는 View를 리턴합니다. Modifier가 여럿인 경우, 스택처럼 쌓이게 됩니다. 때문에 순서에 따라 동작이 달라지고, 아래의 코드에서도 .background()와 .frame()의 순서를 바꾸면 .red가 적용되는 영역이 바뀌게 됩니다. 순서에 따라 달라질 뿐 아니라, 같은 modifier를 여러 번 호출할 경우, 그 효과가 반복됩니다.

Button("Hello World") {
    print(type(of: self.body))
}
.background(Color.red)
.frame(width: 200, height: 200)
// ModifiedContent<ModifiedContent<Button<Text>, _BackgroundModifier<Color>>, _FrameLayout>

 

Why does SwiftUI use "some View" for its view type?

나오자 마자 궁금했었죠. some은 대체 무엇이었을까요? 설명은 다음과 같습니다.

1. We must always return the same type of view.

2. Even though we don't know what view type is going back, the compiler does.

컴파일 타임에 View의 concrete type을 보장함으로써 더 나은 성능을 낼 수 있도록 한다고 합니다.

 

Conditional modifiers

ternary operator를 주로 쓰지만, if를 사용하는 것도 가능합니다. 다만 앞서 말했던 것처럼 modifier는 View의 상태를 변경하는 것이 아니라 ModifiedContent라는 새로운 View를 리턴합니다. 때문에 다음과 같은 코드는 안되는 거죠. some View는 한가지 타입이어야 하는데, .background()를 호출하게 되면 리턴되는 타입은 ModifiedContent입니다.

// ❌ 안되는 코드!!
var body: some View {
    if self.useRedText. {
        return Text("Hello World")
    } else {
        return Text("Hello World")
            .background(Color.red)
    }
}

 

Environment modifiers

경우에 따라서 parent view의 modifier가 일괄적으로 child view에게 적용되기도 합니다. 이러한 modifier를 environment modifier라고 하고, 그 외의 일반적인 modifier를 regular modifier라고 합니다. environment modifier의 경우, child view가 해당 modifier를 override할 수 있는 반면, regular modifier는 child view의 modifier는 무시됩니다. 다만, 특정 modifier가 environment 냐 regular냐에는 법칙 같은 게 없어서, 각각 확인을 해보고 사용해야한다고 합니다. 별로 사용하고 싶은 느낌은 아니네요.

 

Views as properties

가독성을 위해, 혹은 중복 제거를 위해 View를 property로 선언해서 사용하는 방법을 제안하고 있습니다. 다만, 해당 property를 stored property로 선언했을 경우 그를 다른 stored property에서 사용할 경우 객체 생성 시 문제가 발생할 수 있다고 합니다. value type이라 상관없을 것 같은데... computed property를 사용하면 된다고 하네요.

 

View composition, Custom modifiers, Custom containers

이후로 Custom View, Custom Modifier, Custom Container 작성 방법을 소개하고 있습니다. ViewModifier를 생성해서 .modifier()의 argument로 넘겨주는 건 좀 멋지다는 생각이 듭니다. ViewModifier가 어떻게 생겼는지 궁금해서 한번 열어봤는데, Content의 실제 타입을 어떻게 판단하는 건 지 잘 이해가 안갑니다.

'TIL > #100DaysOfSwiftUI' 카테고리의 다른 글

Day 25. Milestone: Projects 1-3  (0) 2020.03.11
Day 24. Project 3, part 2  (0) 2020.03.09
Day 22. Project 2, part 3  (0) 2020.03.08
Day 21. Project 2, part 2  (0) 2020.03.07
Day 20. Project 2, part 1  (0) 2020.03.06

관련글 더보기

댓글 영역