-
[iOS, Swift] (TagCalendar 컴포넌트 2) 뷰의 충돌 감지하기iOS/UI 컴포넌트 2023. 6. 2. 18:30반응형
이전 포스팅에서 드래그하는 뷰를 만들었습니다.
[iOS, Swift] (TagCalendar 컴포넌트 1) 이동하는 뷰 만들기
Swift에서 드래그해서 이동하는 뷰를 만드는 방법을 소개하려고 합니다. 처음에 이러한 디자인을 구현하려고 생각했을 때, 막막했었는데 작은 것 하나하나 조립해서 결국에 원하던 기능을 만들
hhproject.me
이어서 이번 포스팅에서는 뷰가 충돌하는지 확인하고 충돌했을 때 원래의 위치로 돌아가는 기능을 소개하겠습니다.
기능 구현 아이디어
- 원래 위치를 저장한다. (충돌했을 시에 원래 상태로 되돌하기 위함)
- 드래그가 끝난 후 다른 뷰와 겹쳐지는지 확인한다.
- 다른 뷰와 겹쳐지는지 확인하고 겹쳐진다면 원래의 위치로 되돌아간다.
뷰의 원래 위치를 저장하는 부분은 LongPress 이벤트가 실행되었을 때 위치를 저장합니다.
@objc private func handleLongPress(_ gesture: UILongPressGestureRecognizer) { switch gesture.state { case .began: state = .began dragStartLocation = gesture.location(in: self) originalPosition = frame.origin case .changed: updatePosition(with: gesture) case .ended, .cancelled: finishDrag() default: break } }
이벤트가 끝났을 때나 취소되었을 때 finishDrag 함수를 호출합니다.
finishDrag 함수에서는 드래그가 끝난 뒤에 충돌을 감지하는 코드를 작성합니다.
private func finishDrag() { delegate?.tagViewDidMove(self) state = .ended if let superview = superview { for subview in superview.subviews { if let tagView = subview as? MovingView, tagView != self, isOverlapping(with: tagView) { UIView.animate(withDuration: 0.2) { self.frame.origin = self.originalPosition } } } } } func isOverlapping(with other: MovingView) -> Bool { return frame.intersects(other.frame) }
finishDrag 함수에서는 상태값을 ended로 바꿉니다. (뷰의 디자인 변화를 주기 위해서)
뷰의 충돌을 감지하는 코드는 상위 뷰에서 갖고 있는 MovingView들과 overlapping 하는지 확인합니다.
만약 overlapping 한다면 초기의 위치로 변경합니다.
다른 뷰의 프레임과 겹치는지 확인하려면 frame.intersects 함수를 통해서 확인할 수 있습니다.
결과화면
반응형'iOS > UI 컴포넌트' 카테고리의 다른 글
[iOS, Swift] (TagCalendar 컴포넌트 3) 뷰 위치 이동 시 특정 위치(그리드)에만 위치하게 하기 (0) 2023.06.05 [iOS, Swift] (TagCalendar 컴포넌트 1) 이동하는 뷰 만들기 (0) 2023.06.01