[WWDC17] Introducing Drag and Drop(2/4)
이제 Paste Configuration 이 아닌 UIDropInteraction 을 이용하는 방법을 알아보겠습니다.
Drop 을 하기 위한 초기화는 Drag 와 완벽히 동일합니다.
UIDropInteractionDelegate 를 가지는 UIDropInteraction 을 View 에 추가시켜줍니다.
실제 중요한 작업은 UIDropInteractionDelegate 에서 처리하게 됩니다.
지금까지의 내용을 정리한 Dran and Drop API Roadmap 입니다.
파란색은 드래그에 대한 부분입니다.
회색은 드래그 되는 아이템에 대한 부분입니다.
녹색은 드랍에 대한 부분입니다.
이제 이 내용들에 대해 더 상세히 알아보겠습니다.
드래그 앤 드랍이 이뤄지는 모습을 타임라인으로 표현한 모습입니다.
드랍 포지션에 받아줄 뷰가 없을 경우 드래그 앤 드랍 액션은 취소됩니다.
드랍 포지션에서 드랍을 받아주면 드랍 애니메이션과 함께 해당 아이템의 데이터를 받게 됩니다.
이제 타임라인을 기준으로 드래그 앤 드랍의 3단계에 대해 설명하겠습니다.
타임라인에서 실선으로 표시된 부분이 기준이며,
위에 설명한 UIDragInteraction 과 UIDropInteraction 을 설정해 준 상태에서 Delegate 구현부를 중심으로 보게 됩니다.
Drag and Drop API Essential - 1/3 : 드래그할 아이템 얻기
https://developer.apple.com/documentation/uikit/uidraginteractiondelegate/2891010-draginteraction
dragInteraction(_:itemsForBeginning:)
델리게이트를 통해 구현합니다.
드래그 하게 될 아이템을 리턴합니다.
NSItemProvider 를 포함하는 UIDragItem 의 배열입니다.
NSItemProvider 는 주로 NSItemProviderWriting 프로토콜을 준수하는 객체로 만들며, NSString, NSAttributedString, NSURL, UIColor, UIImage 등이 기본적으로 지원합니다.
Drag and Drop API Essential - 2/3 : 드랍 가능 여부 결정
드래그 하는 도중 preview 에 드랍 상태를 표시해 줄 수 있으며, 표시한대로 액션이 이루어지게 됩니다.
- cancel : 드랍할 수 없는 뷰입니다. 손가락을 띠면 그대로 드랍 액션이 취소됩니다.
- copy : 아이템을 복사합니다. 다른 앱에서 드래그 할 때는 반드시 복사만 가능합니다.
- move : 아이템을 이동합니다.
- forbidden : 일시적으로 드랍이 불가능함을 알리는 메시지입니다. 드랍이 가능한 폴더를 생각해봅시다. 여러 개의 폴더 중 한 폴더가 read-only 속성이 켜졌다면 해당 폴더 위에선 forbidden 마크가 표시될 겁니다.
https://developer.apple.com/documentation/uikit/uidropinteractiondelegate/2890888-dropinteraction
이 액션들은 dropInteraction(_:sessionDidUpdate:) -> UIDropProposal 을 통해 반영할 수 있습니다.
경우에 따라 위 네 개 속성 중 하나를 리턴해 줍니다.
Drag and Drop API Essential - 3/3 : 드랍 수행하기
마지막으로 하게 될 드랍 액션은 dropInteraction(_:performDrop:) 을 통해 하게 됩니다.
아래 두 가지 방법이 나와 있습니다.
첫번째는 UIDropSession 의 loadObjects(ofClass:) 를 사용하는 방법입니다.
세션에서 로드할 데이터의 종류를 표시해주면 데이터가 준비되었을 때 closure 를 통해 해당 데이터들을 한 번에 제공해줍니다. 이 때 리턴되는 closure 는 메인큐란 걸 기억해두세요.
두번째는 조금 더 복잡하고 low level 을 이용하는 방법입니다. 세션에 속해 있는 아이템들(드래그로 선택한 아이템들)의 item provider(NSItemProvider) 에 직접 접근하는 방법입니다.
이 때에는 백그라운드큐이므로 리턴된 데이터를 UI 에 바로 반영하기 위해서 DispatchQueue.main.async 를 사용해야 한다는 걸 기억해 두세요.
이제 드래그 앤 드랍의 주요 API 에 대한 정리를 다시 해보겠습니다.
- 드래그 할 아이템들을 선택합니다.
- 드래그한 아이템들을 드랍할 수 있을지 판단합니다.
- 실제로 드랍한 아이템들의 데이터를 가져와서 처리해줍니다.
API 로 정리해보면
- dragInteraction(_:itemsForBeginning:)
- dropInteraction(_:sessionDidUpdate:) -> UIDropProposal
- dropInteraction(_:performDrop:)
지금까지의 내용은 다음 소스에 구현되어 있으니 참고하세요.