@objc func handlePanGesture(_ gesture: UIPanGestureRecognizer) {
guard let targetView = gesture.view,
let containerView = targetView.superview else { return }
switch gesture.state {
case .began:
initialCenter = targetView.center
case .changed:
let translation = gesture.translation(in: containerView)
var newCenter = CGPoint(
x: initialCenter.x + translation.x,
y: initialCenter.y + translation.y
)
// ❗️ 제한 조건: containerView 내부로만 이동
let halfWidth = targetView.bounds.width / 2
let halfHeight = targetView.bounds.height / 2
let minX = halfWidth
let maxX = containerView.bounds.width - halfWidth
let minY = halfHeight
let maxY = containerView.bounds.height - halfHeight
newCenter.x = min(max(newCenter.x, minX), maxX)
newCenter.y = min(max(newCenter.y, minY), maxY)
targetView.center = newCenter
default:
break
}
}
🧠 함수 흐름 설명
🟢 guard let targetView = gesture.view, ...
- 이 제스처가 어떤 뷰(예: UIImageView, UILabel)에 붙어 있는지 확인
- 만약 대상 뷰가 없거나, 상위 뷰가 없다면 함수 종료
👉 gesture.view = 이동 중인 스티커
👉 superview = 이동 범위를 제한할 부모 뷰 (mainImageView가 되겠지)
🟢 gesture.state == .began
initialCenter = targetView.center
- 사용자가 드래그를 시작했을 때, 현재 위치를 저장
- 이후 .changed 상태에서 얼마나 움직였는지 계산할 기준이 됨
🟢 gesture.state == .changed
let translation = gesture.translation(in: containerView)
- 손가락이 얼마나 움직였는지 (translation)를 얻음
- 이건 containerView 기준이야 (즉, mainImageView 좌표계 기준)
var newCenter = CGPoint(
x: initialCenter.x + translation.x,
y: initialCenter.y + translation.y
)
- 이전 위치(initialCenter)에서 손가락이 움직인 거리만큼 더해서 새로운 center 계산
🔒 "📏 이동 제한" 부분
let halfWidth = targetView.bounds.width / 2
let halfHeight = targetView.bounds.height / 2
- center가 기준이므로, 뷰의 절반 크기만큼은 양쪽 여백으로 확보해야 함
→ 그래야 뷰 전체가 containerView 안에 있도록 만들 수 있어
let minX = halfWidth
let maxX = containerView.bounds.width - halfWidth
let minY = halfHeight
let maxY = containerView.bounds.height - halfHeight
- center.x의 최소값은 왼쪽 끝에서 halfWidth만큼 떨어진 곳
- center.x의 최대값은 오른쪽 끝에서 halfWidth만큼 떨어진 곳
- 마찬가지로 Y도 위아래 같은 원리
newCenter.x = min(max(newCenter.x, minX), maxX)
newCenter.y = min(max(newCenter.y, minY), maxY)
- center.x가 minX보다 작으면 → minX로 고정
- center.x가 maxX보다 크면 → maxX로 고정
👉 이렇게 하면 오버레이 뷰 전체가 containerView 바깥으로 못 나감
(뷰의 중앙 기준으로 바깥 경계를 계산하니까 정확함)
✅ 이렇게 되면
- 사용자가 스티커를 드래그하더라도
- mainImageView 안에서만 움직일 수 있음
- 화면 밖으로 나가는 일이 절대 없음!
'Project > PhotoDiary' 카테고리의 다른 글
🎶 이미지 테두리에 만드는 방법 (0) | 2025.06.25 |
---|---|
👌 컬렉션뷰내의 셀의 위치를 가운데로 오게 하는 방법 (0) | 2025.06.17 |
👍 사용자가 버튼을 눌렀을 때 현재 보여지고 있는 시트(DiarySheetViewController)를 닫고, 그 이후에 PhotoDiaryViewController를 전체화면으로 띄우기 위한 흐름 (0) | 2025.06.16 |