- EqutableView란?
> EqutableView는 이전 값과 비교하여 새 값이 이전 값과 동일한 경우 자식 업데이트를 방지하도록 설계된 뷰입니다.
`iOS 13.0+` `iPadOS 13.0+` `tvOS 13.0` `watchOS 6.0+` `visionOS 1.0+ Beta
[apple-docs-EqutableView](https://developer.apple.com/documentation/swiftui/equatableview)
💡 들어가기 전.
- 아래의 개념에 대한 지식이 반드시 필요함. 필요한 이유는 글 제일 아래에서 설명
- [Plain ol' Data](https://rldd.tistory.com/552)
EqutableView Usage
1. 내가 EqutableView로 만들고자 하는 곳에 Equtable을 채택
struct LuckyBoxStateView: View, Equtable { ... }
2. 사용하는 곳에서
Equtable(content: LuckyBoxStateView(text: text))
or
/// ✅ 요 방식이 선언적이라 더 나음
LuckyBoxStateView(text: text)
.equtable()
예제 시나리오
- 내가 만드는 서비스에 확률형 아이템인 럭키박스가 있다고 가정.
- 럭키박스를 구매시 특정 확률에 따라 배수가 결정.
- 럭키박스 오픈시 결정된 배수가 UI에 나타나는 방식.
전체 적용된 EqutableView 코드
enum LuckyBoxState: String {
case state1 = "x10배"
case state2 = "x2배"
case state3 = "x0.5배"
case state4 = "x0.1배"
static func result(number: Double) -> String {
if number < 5 {
return LuckyBoxState.state1.rawValue
} else if number < 15 {
return LuckyBoxState.state2.rawValue
} else if number < 45 {
return LuckyBoxState.state3.rawValue
} else {
return LuckyBoxState.state4.rawValue
}
}
}
struct ContentView: View {
@State private var number: Double = 0
@State private var count: UInt = 0
private let size: CGFloat = 200
var body: some View {
Self._printChanges()
return VStack {
LuckyBoxStateView(number: number)
.equatable()
.frame(width: size, height: size * 2 / 3, alignment: .center)
.background(.blue.opacity(0.5))
.cornerRadius(10)
Button {
number = Double.random(in: 0..<100)
count += 1
} label: {
Text("럭키박스 오픈")
}
Text("당첨번호: \(LuckyBoxState.result(number: number))")
Text("오픈차수: \(count)")
}
}
}
struct LuckyBoxStateView: View, Equatable {
var number: Double
static func == (lhs: LuckyBoxStateView, rhs: LuckyBoxStateView) -> Bool {
let l = LuckyBoxState.result(number: lhs.number)
let r = LuckyBoxState.result(number: rhs.number)
return l == r
}
var body: some View {
Self._printChanges()
return VStack(alignment: .center) {
Text("🎊 당첨 🎊")
Spacer()
.frame(height: 20)
Text(LuckyBoxState.result(number: number))
.font(.system(size: 40, weight: .semibold))
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
보다시피 중간에 LuckBoxStateView가 업데이트 되지 않음

🚨 여기서 주의해야 하는 점 🚨
이거 진짜 중요함. 경우에 따라서는 EqutableView로 만들어도 작동하지 않는 경우도 존재.
- 만약 LuckyBoxStateView에 member가 POD 타입만 존재하는 경우 경우에는 EqutableView임에도 해당 `static func ==`이 호출되지 않고 LuckyBoxStateView의 init이 호출됩니다.
- non-POD가 하나라도 존재하는 경우 해당 부분은 `static func ==`으로 관리되며 @State와 @Biding의 경우에는 내부에서 자체적으로 `static func ==`을 결정하고 있습니다.
(참고)
https://ios-development.tistory.com/1111
'apple > SwiftUI, Combine' 카테고리의 다른 글
[SwiftUI] NavigationLink 화살표 없애기 (0) | 2024.03.11 |
---|---|
SwiftUI keyboard 이벤트 감지하기 (0) | 2024.03.06 |
[iOS] NavigationSplitView (0) | 2023.08.05 |
Swift Combine Networking (0) | 2022.06.11 |
[Combine] Let's study Combine! (0) | 2022.06.03 |