관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] NSItemProvider 개념 (drag and drop, copy and paste, 복사하기) 본문

iOS 응용 (swift)

[iOS - swift] NSItemProvider 개념 (drag and drop, copy and paste, 복사하기)

jake-kim 2023. 7. 26. 01:59

NSItemProvider 개념

  • drag and drop이나 copy and paste 동작 할 때 delegate나 데이터를 주입할 때 NSItemProvider가 등장하는데, 현재의 앱이 다른 앱에 데이터를 전달하는 목적으로 사용
    • drag and drop: 화면 하나에 여러개의 앱이 띄워져 있을 수 있는 경우, 다른 앱으로 drop하여 아이템을 전달할 때 이 provider에 담아서 전송
    • copy and paste: 복사를 할 때 어떤 데이터를 복사할지 provider에 입력이 가능

https://developer.apple.com/documentation/foundation/nsitemprovider

ex) UICollectionView를 사용하여 Drag and Drop 컬렉션 뷰를 만들 때 NSItemProvider가 등장

(drag and drop 구현 포스팅 글)

 

[iOS - swift] DragDropCollectionView 구현 방법 (dragDelegate, dropDelegate, 드래그앤 드랍)

주의사항 애플에서 제공하는 기본 Drag, Drop을 사용하면, UITextField에서 becomeFirstResponder 상태에서 resignFirstResponder로 변경되므로 셀을 이동시킬때 키보드가 내려가므로 주의 키보드가 내려가지 않

ios-development.tistory.com

  • view.dragDelegate = self 델리게이트 설정하면 아래와 같이 델리게이트 메소드에서 [UIDragItem]를 리턴이 필요
    • UIDragItem은 NSItemProvider 타입을 받도록 되어 있는 상태
    • 여기에 특정 데이터를 담으면 다른 앱으로 drop했을때 아이템 전달이 가능
extension ViewController: UICollectionViewDragDelegate {
    func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
        [UIDragItem(itemProvider: NSItemProvider())]
    }
}

copy and paste에서 NSItemProvider 사용해보기

  • clipboard를 사용하여 텍스트를 복사하는 가장 단순한 방법은 UIPasteboard 타입을 직접 접근하는 방법
UIPasteboard.general.string
  • NSItemProvider를 사용하면 pasteboard에 저장되는 시간이라던지 디테일한 것들도 제어가 가능
  • 예제에 사용할 뷰 준비
    • UITextView가 하나 있는 UIViewController

import UIKit

class ViewController: UIViewController {
    private let textView: UITextView = {
        let view = UITextView()
        view.text = "텍스트... "
        view.textColor = .white
        view.font = .systemFont(ofSize: 20)
        view.backgroundColor = .gray
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.addSubview(textView)
        NSLayoutConstraint.activate([
            textView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            textView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            textView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            textView.heightAnchor.constraint(equalToConstant: 100),
        ])
    }
}
  • UITextView 외의 영역을 long press하면 특정 문자열이 10초동안만 복사되게끔 처리
override func viewDidLoad() {
	...
    
    let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress))
    view.addGestureRecognizer(longPressGesture)
}

@objc func handleLongPress(gesture: UILongPressGestureRecognizer) {
    // TODO
}
  • handleLongPress(gesture: ) 메소드 구현
    • gesture가 .began일때만 복사
@objc func handleLongPress(gesture: UILongPressGestureRecognizer) {
    guard gesture.state == .began else { return }
    let textToCopy = "김종권의 iOS 앱 개발 알아가기"

    // TODO
}
  • UIPasteboard.general을 가져오고, 여기다가 NSItemProvider를 주입
    • 10초동안만 복사되도록 설정
let itemProvider = NSItemProvider(object: textToCopy as NSString)
let pasteboard = UIPasteboard.general
pasteboard.setItemProviders([itemProvider], localOnly: true, expirationDate: Date().addingTimeInterval(10))
  • 복사 성공에 관한 alert 추가
// 알림 메시지 표시
let alert = UIAlertController(
    title: "복사 성공!",
    message: "clipboard에 복사되었습니다.",
    preferredStyle: .alert
)
let dismissAction = UIAlertAction(title: "OK", style: .default)
alert.addAction(dismissAction)
present(alert, animated: true)

(완성)

* 전체 코드: https://github.com/JK0369/ExNSItemProvider

* 참고

https://developer.apple.com/documentation/foundation/nsitemprovider

Comments