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 | 31 |
Tags
- 리팩토링
- swift documentation
- rxswift
- 애니메이션
- map
- uitableview
- tableView
- Observable
- Human interface guide
- ribs
- 리펙터링
- clean architecture
- MVVM
- HIG
- combine
- ios
- UITextView
- uiscrollview
- Refactoring
- 클린 코드
- swiftUI
- Clean Code
- SWIFT
- RxCocoa
- Protocol
- UICollectionView
- collectionview
- Xcode
- 스위프트
- 리펙토링
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - SwiftUI] 뷰에서 if, else 구분해야할때 id 활용하는 방법 (SwiftUI의 id) 본문
iOS 응용 (SwiftUI)
[iOS - SwiftUI] 뷰에서 if, else 구분해야할때 id 활용하는 방법 (SwiftUI의 id)
jake-kim 2025. 2. 19. 22:32if, else 문을 쓰는 케이스
- 만약 아래처럼 버튼을 눌렀을 때 특정 뷰에 애니메이션을 주어야하는 경우?
- 구현 아이디어
- 뷰를 만들 때 if, else문이 없이 아래처럼 animation을 주는 방법도 존재
- 버튼이 눌릴때마다 isFlipped 값을 변경
@State var isFlipped = false
Text("🚀 SwiftUI Power!")
.font(.largeTitle)
.fontWeight(.bold)
.foregroundColor(isFlipped ? .blue : .purple)
.scaleEffect(isFlipped ? 1.5 : 0.5)
.rotationEffect(.degrees(isFlipped ? 360 : -180))
.opacity(isFlipped ? 1 : 0.5)
.animation(.spring(response: 0.6, dampingFraction: 0.5), value: isFlipped)
- 하지만 transition을 사용하여 구현된 상태에서는 뷰가 새로 그려질때인 if, else 문일때만 동작하는데, 이 때 아래처럼 사용하는 경우가 있음
@State private var isFlipped = false
if isFlipped {
animationText
} else {
animationText
}
var animationText: some View {
Text("🚀 SwiftUI Power!")
...
.transition(.asymmetric(insertion: .scale.combined(with: .opacity),
removal: .opacity))
.animation(.spring(response: 0.6, dampingFraction: 0.5), value: isFlipped)
}
- if, else 문 둘 다 동일한 뷰를 반환하기 때문에 이상한 코드처럼 보일 수 있으므로 이 경우는 if, else가 아닌 id를 활용하는것이 더욱 명확
id 개념
- SwiftUI에서 id라는 메서드가 View의 extension으로 있는데, 이 id를 사용하면 위 문제 해결이 가능
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
extension View {
/// Binds a view's identity to the given proxy value.
///
/// When the proxy value specified by the `id` parameter changes, the
/// identity of the view — for example, its state — is reset.
@inlinable public func id<ID>(_ id: ID) -> some View where ID : Hashable
}
- id는 단어 그대로 뷰에 id를 부여하는 것이며 id값이 달라지면 동일한 샘김새일 지라도 다른 뷰라고 판단됨
- 즉, if, else문에서 동일한 뷰를 반환하는 것보단 단순히 같은 뷰에 id를 다르게 달아주면 되는 것
- ID는 Hashable 타입이면 되므로 String, Bool과 같은 primitive type들은 모두 사용 가능
- 아래 코드를 id를 활용하여 변경
if isFlipped {
animationText
} else {
animationText
}
변경 후)
- if, else로 표현하는 것보다 "이 뷰는 동일한 구현으로 되어있지만 isFlipped에 따라 다른 뷰를 사용한다"라는 의미가 명확하게 됨
animationText
.id(isFlipped)
전체 코드)
struct ContentView: View {
@State var toggle = false
var body: some View {
AnimatedTextView()
}
}
struct AnimatedTextView: View {
@State private var isFlipped = false
var body: some View {
VStack {
if isFlipped {
animationText
} else {
animationText
}
animationText
.id(isFlipped)
Spacer().frame(height: 50)
Button(action: {
withAnimation {
isFlipped.toggle()
}
}) {
Text("Change Text")
.padding()
.background(Color.black)
.foregroundColor(.white)
.cornerRadius(10)
}
}
}
var animationText: some View {
Text("🚀 SwiftUI Power!")
.font(.largeTitle)
.fontWeight(.bold)
.foregroundColor(.blue)
.scaleEffect(1.5)
.rotationEffect(.degrees(360))
.opacity(1)
.transition(.asymmetric(insertion: .scale.combined(with: .opacity),
removal: .opacity))
.animation(.spring(response: 0.6, dampingFraction: 0.5), value: isFlipped)
}
}
'iOS 응용 (SwiftUI)' 카테고리의 다른 글
Comments