문제상황
개요
테이블뷰 델리게이트가 제공해주는 Trailing Swipe를 사용하지 않고 위처 커스텀 테이블뷰 셀 안에 있는 뷰에 팬제스쳐를 넣었다.
그랬더니 셀의 개수가 많아져서 세로 스크롤이 되어야 할 때에 스크롤이 되지 않는 문제가 발생했다.
ㄴㅇㄱ
코드는 위와 같다.
셀 안에 Pan Gesture를 넣었더니 테이블 뷰에서 셀 안에 있는 팬제스쳐에게 이벤트를 뺏겨 세로 스크롤이 되지 않는 문제가 발생했다.
문제해결
아이디어
세로 스크롤은 컬렉션뷰의 기본 동작이지만, 셀 내부 제스처가 우선순위를 가지며 충돌 발생했다.
즉, 제스쳐를 관리하는 UIGestureRecognizerDelegate
프로토콜을 활용해 제스처 동작 조건을 제한한다.
수평 스와이프는 셀의 커스텀 동작으로, 수직 스와이프는 컬렉션뷰 스크롤로 이벤트 전달
문제해결 과정
@MainActor open class UITableViewCell
: UIView, NSCoding, UIGestureRecognizerDelegate { }
UITableViewCell의 선언문이다.
UIView을 상속 받고 있고, NSCoding과 UIGestureRecognizerDelegate을 채택하고 있다.
여기서 말하는 UIGestureRecognizerDelegate이 내가 다루어야할 프로토콜이다.
UIGestureRecognizerDelegate 안에는 아래 두 개의 주요 메소드가 있다.
- 방향 감지:
gestureRecognizerShouldBegin(_:)
- 동시 인식 허용:
shouldRecognizeSimultaneouslyWith
gestureRecognizerShouldBegin(_:)
에서 터치 방향 판별을 하고,
shouldRecognizeSimultaneouslyWith
로 다중 제스처 처리할 것이다.
// MARK: - UIGestureRecognizer Delegate
extension TimeSlotTableViewCell {
override func gestureRecognizer(
_ gestureRecognizer: UIGestureRecognizer,
shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer
) -> Bool {
// 수평 스와이프 제스처와 테이블뷰의 수직 스크롤 제스처가 동시에 인식되도록 허용
return true
}
override func gestureRecognizerShouldBegin(
_ gestureRecognizer: UIGestureRecognizer
) -> Bool {
if let panGesture = gestureRecognizer as? UIPanGestureRecognizer {
let velocity = panGesture.velocity(in: contentView)
// 수평 이동이 수직 이동보다 클 경우 제스처 인식 (수평 스와이프)
return abs(velocity.x) > abs(velocity.y)
}
return true
}
}
셀 내부에 추가한 팬 제스처가 수평 스와이프에만 반응하도록 하고, 동시에 세로 스크롤 제스처가 인식되도록 했다.
처음에 `extension TimeSlotTableViewCell: UIGestureRecognizerDelegate {` 자꾸 이렇게 선언했는데 알고 보니 테이블뷰는 제스쳐에 의해 스크롤이 가능했던 것이었다.
셀에서 불필요하게 프로토콜을 다시 선언할 필요가 없으며, 상위 클래스에서 이미 채택되어 있음을 확인하였다.
배운 점
- 제스처 우선순위 관리
- 특정 방향의 제스처만 활성화하여 이벤트 충돌 방지
velocity(in:)
으로 스와이프 방향을 계산해 로직 분기
- 컬렉션뷰 구조 이해
- 컬렉션뷰는 내부적으로 스크롤 뷰의 팬 제스처를 사용함
- 커스텀 제스처 추가 시 기존 동작과의 충돌을 고려해야 함
- 델리게이트 활용
UIGestureRecognizerDelegate
메서드로 제스처 동작을 세밀하게 제어- 프로토콜 중복 선언 없이 기존 클래스의 델리게이트 기능 활용
참조 링크
https://developer.apple.com/documentation/uikit/uigesturerecognizerdelegate
UIGestureRecognizerDelegate | Apple Developer Documentation
A set of methods implemented by the delegate of a gesture recognizer to fine-tune an app’s gesture-recognition behavior.
developer.apple.com
'📱 iOS > UIKit' 카테고리의 다른 글
[문제해결] UITableViewCell에서 CornerRadius 개별 설정 시 초기 레이아웃 문제를 비동기 재귀로 해결하기 (1) | 2025.02.28 |
---|---|
[UIKit] 뷰의 Corner Radius 각각 다르게 처리하기 (with CACornerMask, UIBezierPath, CAShapeLayer) (0) | 2025.02.28 |
[UIKit] UIMenu 사용기 (1) | 2024.12.10 |
[UIKit] CollectionViewCell 드래그 앤 드랍 구현하기 (0) | 2024.12.01 |
[UIKit] iOS 15.0 이상에서 UIButton 안에 있는 이미지 사이즈 조절하기 (3) | 2024.11.15 |