[swift] RxDataSources를 사용한 테이블 뷰의 드래그 앤 드롭 처리 방법

테이블 뷰에서 셀의 드래그 앤 드롭 기능을 구현하기 위해서는 RxDataSources를 사용하는 것이 편리합니다. 이를 통해 테이블 뷰의 데이터 소스를 쉽게 관리하고, 드래그 앤 드롭 이벤트를 처리할 수 있습니다. 이번 글에서는 Swift 언어와 RxSwift 라이브러리를 기반으로 RxDataSources를 사용한 테이블 뷰의 드래그 앤 드롭 처리 방법을 살펴보겠습니다.

필요한 라이브러리 설치

먼저 프로젝트에 RxSwift와 RxCocoa 라이브러리를 설치해야 합니다. CocoaPods를 사용한다면, Podfile에 다음과 같이 추가하세요:

target 'YourProject' do
  use_frameworks!
  pod 'RxSwift'
  pod 'RxCocoa'
end

그리고 터미널에서 pod install 명령을 실행하여 라이브러리를 설치하세요.

Drag and Drop 기능 활성화

테이블 뷰의 드래그 앤 드롭 기능을 활성화하기 위해 dragInteractionEnabled 속성을 true로 설정해야 합니다. 이를 위해 테이블 뷰 컨트롤러의 viewDidLoad() 메소드에서 다음과 같이 설정하세요:

tableView.dragInteractionEnabled = true

드래그 앤 드롭 처리

이제 드래그 앤 드롭을 처리하는 코드를 작성해보겠습니다. 먼저 드래그 앤 드롭 이벤트를 처리할 테이블 뷰 컨트롤러에 다음과 같은 프로퍼티와 메소드를 추가합니다:

private var items = Variable<[String]>(["Item 1", "Item 2", "Item 3"])

func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
    let item = items.value[indexPath.row]
    let itemProvider = NSItemProvider(object: item as NSString)
    let dragItem = UIDragItem(itemProvider: itemProvider)
    dragItem.localObject = item
    return [dragItem]
}

func tableView(_ tableView: UITableView, performDropWith coordinator: UITableViewDropCoordinator) {
    guard let destinationIndexPath = coordinator.destinationIndexPath else { return }
    coordinator.session.loadObjects(ofClass: NSString.self) { items in
        guard let item = items.first as? String else { return }
        // 드랍한 아이템을 destinationIndexPath 위치로 이동시킴
        self.items.value.remove(at: self.items.value.firstIndex(of: item)!)
        self.items.value.insert(item, at: destinationIndexPath.row)
    }
}

위의 코드에서는 items라는 변수를 통해 테이블 뷰의 아이템을 관리합니다. tableView(_:itemsForBeginning:at:) 메소드는 드래그하는 셀을 위한 UIDragItem 객체를 생성하고 반환합니다. tableView(_:performDropWith:) 메소드는 드롭한 아이템을 처리하여 테이블 뷰의 데이터를 업데이트합니다.

데이터 바인딩

이제 items 배열을 뷰 모델과 바인딩하여 테이블 뷰에 데이터를 표시해보도록 하겠습니다. 뷰 모델에 items 프로퍼티를 추가하고, 테이블 뷰 컨트롤러에서 이를 구독하여 데이터를 업데이트할 수 있습니다.

struct ViewModel {
    let items: Observable<[String]>
}

class TableViewController: UITableViewController {
    let disposeBag = DisposeBag()
    
    let viewModel = ViewModel(items: items.asObservable())
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        items.asObservable()
            .bind(to: tableView.rx.items(cellIdentifier: "CellIdentifier", cellType: UITableViewCell.self)) { (_, element, cell) in
                cell.textLabel?.text = element
            }
            .disposed(by: disposeBag)
    }
}

위의 코드에서는 ViewModel 구조체에 items 프로퍼티를 추가하여 데이터를 관리합니다. 그리고 뷰 모델의 items를 테이블 뷰에 바인딩하여 데이터를 업데이트합니다.

마무리

RxSwift와 RxDataSources를 사용하여 테이블 뷰의 드래그 앤 드롭 기능을 구현하는 방법을 알아보았습니다. RxDataSources는 테이블 뷰의 데이터 관리 및 드래그 앤 드롭 처리를 편리하게 해주는 라이브러리입니다. 이를 활용하여 손쉽게 드래그 앤 드롭 기능을 구현할 수 있으며, 데이터 바인딩을 통해 테이블 뷰의 업데이트를 간단하게 처리할 수 있습니다.

참고자료: