티스토리 뷰
728x90
반응형
[SwiftUI] re-rendering, re-draw 추측 에서 SwiftUI가 내부적으로 리렌더링을 어떻게 결정하는 지 추측해보았는데요
리렌더링을 커스터마이징 (?) 할 수 있는 방법도 있습니다.
# 1. SwiftUI 는 다시 안그리는데, 나는 다시 그리고 싶은 경우
뷰는 extract subview를 하면 별도의 identity를 부여받아, 부모 뷰와 같이 리렌더링이 안됩니다.
부모의 body가 재호출될 때 extracted 한 서브뷰를 항상 같이 다시 그리고 싶으면 id를 활용합니다.
[ 기본 동작 ]
ContentView의 body가 호출될 때 NoMatterText는 다시 안그려짐
struct ContentView: View {
@State private var isOn = true
private var lightStack: some View {
VStack(spacing: 10) {
Text(isOn ? "ON" : "OFF")
.background(.random)
Button {
isOn.toggle()
} label: {
Text("🔦")
}.background(.random)
}
}
var body: some View {
lightStack
Spacer()
.frame(height: 50)
.background(.random)
NoMatterText()
}
}
struct NoMatterText: View {
var body: some View {
Text("NO MATTER!")
.background(.random)
}
}
[ 커스마이징 후 동작 ]
ContentView의 body가 호출될 때 NoMatterText도 다시 그려짐 (identity를 내가 갱신하기 때문)
struct ContentView: View {
@State private var isOn = true
private var lightStack: some View {
VStack(spacing: 10) {
Text(isOn ? "ON" : "OFF")
.background(.random)
Button {
isOn.toggle()
} label: {
Text("🔦")
}.background(.random)
}
}
var body: some View {
lightStack
Spacer()
.frame(height: 50)
NoMatterText().id(UUID())
}
}
# 2. SwiftUI 는 다시 그리는데, 나는 다시 안그리고 싶은 경우
State와 달리 ObservableObject는 구체적인 dependency에 따라 리렌더링을 하지 않습니다.
관련 없는 서브뷰가 다시 그려지는 게 싫으면 Equatable 을 활용합니다.
[ 기본 동작 ]
특정 dependency와 관련 없는 서브뷰들도 다 다시 그려짐
class SomeState: ObservableObject {
@Published var isOn = true
@Published var noMatterText = "NO MATTER!"
}
struct ContentView: View {
@StateObject var state = SomeState()
var body: some View {
LightStack(isOn: $state.isOn)
Spacer()
.frame(height: 50)
NoMatterText(text: $state.noMatterText)
}
}
struct LightStack: View {
@Binding var isOn: Bool
var body: some View {
VStack(spacing: 10) {
Text(isOn ? "ON" : "OFF")
.background(.random)
Button {
isOn.toggle()
} label: {
Text("🔦")
}.background(.random)
}
}
}
struct NoMatterText: View {
@Binding var text: String
var body: some View {
Text(text)
.background(.random)
.onTapGesture {
text += "!"
}
}
}
[ 커스마이징 후 동작 ]
특정 dependency랑 관련 있는 서브뷰만 다시 그려짐 / 관련 없는 서브뷰는 안그려짐 (equality를 내가 정했기때문)
class SomeState: ObservableObject {
@Published var isOn = true
@Published var noMatterText = "NO MATTER!"
}
struct ContentView: View {
@StateObject private var state = SomeState()
var body: some View {
LightStack(isOn: $state.isOn)
Spacer()
.frame(height: 50)
NoMatterText(text: $state.noMatterText)
}
}
private struct LightStack: View, Equatable {
@Binding var isOn: Bool
var body: some View {
VStack(spacing: 10) {
Text(isOn ? "ON" : "OFF")
.background(.random)
Button {
isOn.toggle()
} label: {
Text("🔦")
}.background(.random)
}
}
static func == (lhs: LightStack, rhs: LightStack) -> Bool {
lhs.isOn == rhs.isOn
}
}
struct NoMatterText: View, Equatable {
@Binding var text: String
var body: some View {
Text(text)
.background(.random)
.onTapGesture {
text += "!"
}
}
static func == (lhs: NoMatterText, rhs: NoMatterText) -> Bool {
lhs.text == rhs.text
}
}
참고로 SwiftUI에 equatable() 이란 modifier도 있는데,
이것을 안쓰고 Equatable 만 채택해줘도 잘 동작하더라구요!
반응형
'🍏 > SwiftUI + Combine' 카테고리의 다른 글
[Combine] 네트워킹 (0) | 2023.01.13 |
---|---|
[SwiftUI] rotationEffect, scaleEffect (0) | 2023.01.06 |
[SwiftUI] re-rendering, re-draw 추측 (1) | 2022.11.16 |
[SwiftUI] accessibilityRepresentation 과 accessibilityChildren (0) | 2021.10.27 |
[SwiftUI] iOS13에서 onChange(of:perform:) 을 사용하고 싶을 때 (2) | 2021.09.03 |
댓글
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- Django Firebase Cloud Messaging
- Flutter Spacer
- Django FCM
- Sketch 누끼
- Python Type Hint
- SerializerMethodField
- ipad multitasking
- Flutter getter setter
- 장고 Custom Management Command
- Dart Factory
- flutter 앱 출시
- flutter deep link
- 플러터 싱글톤
- Flutter Text Gradient
- flutter build mode
- 플러터 얼럿
- METAL
- drf custom error
- Django Heroku Scheduler
- Watch App for iOS App vs Watch App
- ribs
- PencilKit
- Flutter 로딩
- github actions
- flutter dynamic link
- Flutter Clipboard
- DRF APIException
- 장고 URL querystring
- cocoapod
- 구글 Geocoding API
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함