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
- 리펙터링
- map
- swiftUI
- ios
- UITextView
- HIG
- Human interface guide
- Observable
- collectionview
- tableView
- Clean Code
- MVVM
- UICollectionView
- combine
- clean architecture
- uitableview
- ribs
- Refactoring
- Protocol
- 리팩토링
- uiscrollview
- swift documentation
- SWIFT
- 애니메이션
- 스위프트
- RxCocoa
- rxswift
- 리펙토링
- 클린 코드
- Xcode
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] 3. long press gesture와 애니메이션 - 드래그와 cornerRadius, shadow 효과 (CABasicAnimation) 본문
UI 컴포넌트 (swift)
[iOS - swift] 3. long press gesture와 애니메이션 - 드래그와 cornerRadius, shadow 효과 (CABasicAnimation)
jake-kim 2023. 7. 20. 00:501. long press gesture와 애니메이션 - 드래그 구현 방법 (snapshotView, CGAffineTransform)
3. long press gesture와 애니메이션 - 드래그와 cornerRadius, shadow 효과 (CABasicAnimation)
4. long press gesture와 애니메이션 - UIStackView에 DragDrop 적용 (DragDropStackView 구현)
5. long press gesture와 애니메이션 - gesture 도중 화면 끝으로 가면 자동으로 스크롤되는 기능 구현 (#Horizontal Scroll, #수평 스크롤)
뷰 준비
지금까지 구현된 부분 내용은 이전 포스팅 글 참고
- long press gesture를 사용하여 began, changed, ended 상태에따라 애니메이션 처리
- began 시점에 다른 뷰들은 Affine 변환을 통해 작게하고, 이동시킬 뷰는 크게하여 애니메이션 효과 적용
- 뷰 이동은 Affine 변환 사용
drag 시작 시, 다른 뷰들에 shadow opacity 효과주기
- 구현 아이디어
- gesture의 began에서 CABasicAnimation(keyPath: "shadowOpacity")를 사용하여 그림자 효과를 적용
- gesture의 ended에서 애니메이션 제거 (layer.removeAllAnimation())
아래 코드에서 prepareDragAnimation() 부분 아래에서 구현)
@objc private func handleLongPress(_ gesture: UILongPressGestureRecognizer) {
switch gesture.state {
case .began:
handleBegan(gesture)
case .changed:
handleChanged(gesture)
default:
// ended, canceled, failed
handleEnded(gesture)
}
}
private func handleBegan(_ gesture: UILongPressGestureRecognizer) {
...
UIView.animate(
withDuration: 0.4,
delay: 0,
usingSpringWithDamping: 0.8,
initialSpringVelocity: 0,
options: [.allowUserInteraction, .beginFromCurrentState],
animations: { self.prepareDragAnimation() },
completion: nil
)
}
private func prepareDragAnimation() {
...
// TODO: shadow animation
}
- CABasicAnimation(keyPath: "shadowOpacity")를 사용
- opacity 0부터 (fromValue), 0.8 그림자가 생기도록 적용
// shadow animation
let shadowOpacityAnimation = CABasicAnimation(keyPath: "shadowOpacity")
shadowOpacityAnimation.fromValue = 0
shadowOpacityAnimation.toValue = 0.8
shadowOpacityAnimation.isRemovedOnCompletion = false
shadowOpacityAnimation.fillMode = .forwards
[otherView, anotherView]
.forEach { subview in
subview.layer.add(shadowOpacityAnimation, forKey: "animation_shadow_opacity")
}
- gesture의 ended 상태에서는 애니메이션을 제거
// shadow animation
[otherView, anotherView]
.forEach { subview in
UIView.animate(
withDuration: 0.3,
animations: {
subview.layer.removeAllAnimations()
}
)
}
shadow 효과 여러개 한꺼번에 주기
- 위에까지 구현하면 shadow offset y 값이 상단으로 향해 있으므로, 자연스럽게 아래로 내려가도록 구현이 필요
- CABasicAnimation(keyPath: "shadowOffset.height")를 사용
- layer.add에 shadowOffset.height 애니메이션도 같이 삽입하면 완성
// shadow animation
let shadowOpacityAnimation = CABasicAnimation(keyPath: "shadowOpacity")
...
let shadowOffsetHeightAnimation = CABasicAnimation(keyPath: "shadowOffset.height")
shadowOffsetHeightAnimation.fromValue = 0
shadowOffsetHeightAnimation.toValue = 3
shadowOffsetHeightAnimation.isRemovedOnCompletion = false
shadowOffsetHeightAnimation.fillMode = .forwards
[otherView, anotherView]
.forEach { subview in
subview.layer.add(shadowOpacityAnimation, forKey: "animation_shadow_opacity")
subview.layer.add(shadowOffsetHeightAnimation, forKey: "animation_shadow_offset_height")
}
- CABasicAnimation(keyPath: "shadowRadius")를 사용
- 마찬가지로 layer.add에 shadowOffset.height 애니메이션도 같이 사용
// shadow animation
let shadowOpacityAnimation = CABasicAnimation(keyPath: "shadowOpacity")
...
let shadowOffsetHeightAnimation = CABasicAnimation(keyPath: "shadowOffset.height")
...
let shadowRadiusAnimation = CABasicAnimation(keyPath: "shadowRadius")
shadowRadiusAnimation.fromValue = 0
shadowRadiusAnimation.toValue = 8
shadowRadiusAnimation.isRemovedOnCompletion = false
shadowRadiusAnimation.fillMode = .forwards
[otherView, anotherView]
.forEach { subview in
subview.layer.add(shadowOpacityAnimation, forKey: "animation_shadow_opacity")
subview.layer.add(shadowOffsetHeightAnimation, forKey: "animation_shadow_offset_height")
subview.layer.add(shadowRadiusAnimation, forKey: "animation_shadow_radius")
}
(완성)
'UI 컴포넌트 (swift)' 카테고리의 다른 글
Comments