프로젝트 개선 및 리팩토링 사항
- 프로젝트 진행하면서 시간 및 구조적인 문제로 drag and drop 구현이 힘들었음
- iOS native 기능으로 테이블뷰에 drag and drop을 구현해보고 공부해보았음
- 생각했던 기능과 달랐던 점 을 발견
- 최근 출시 앱 및 디자인 UX 면에서 drag and drop을 많이 사용하지 않음
- 달랐던 점: 테이블뷰의 해당 셀을 1초 정도 누르고 있어야 드래그앤 드랍 상태가 됨 여러개의 데이터 추가하려면 매우 불편
- 버튼을 누르면 바로 추가되는 것이 사용자 입장에서 더 편할 것 같다
- 잘못추가된 데이터를 수정할때에는 필요할 수도 But 기획의 의도에 따라...
override func viewDidLoad() {
super.viewDidLoad()
leftTableView.dataSource = self
rightTableView.dataSource = self
leftTableView.dragDelegate = self
leftTableView.dropDelegate = self
rightTableView.dragDelegate = self
rightTableView.dropDelegate = self
leftTableView.dragInteractionEnabled = true
rightTableView.dragInteractionEnabled = true
leftTableView.frame = CGRect(x: 0, y:40, width: 150, height: 400)
rightTableView.frame = CGRect(x: 150, y: 40, width: 150, height: 400)
leftTableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
rightTableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
view.addSubview(leftTableView)
view.addSubview(rightTableView)
}
- 두개의 테이블뷰를 만들어서 drag and drop 기능으로 문자열이 이동하게 만들 예정
- dragDelegate 와 dropDelegate 를 self로 지정해주고 테이블뷰의 dragInteractionEnabled를 true로 설정해줘서 드래그 앤 드랍이 작동할 수 있게 만듬
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == leftTableView{
return leftItems.count
} else {
return rightItems.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
if tableView == leftTableView {
cell.textLabel?.text = leftItems[indexPath.row]
} else {
cell.textLabel?.text = rightItems[indexPath.row]
}
return cell
}
}
- 테이블뷰로 데이터와 섹션 row 개수 분기처리
extension ViewController: UITableViewDragDelegate {
func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
let string = tableView == leftTableView ? leftItems[indexPath.row] : rightItems[indexPath.row]
guard let data = string.data(using: .utf8) else {return [] }
let itemProvider = NSItemProvider(item: data as NSData, typeIdentifier: kUTTypePlainText as String)
return [UIDragItem(itemProvider: itemProvider)]
}
}
- 선택한 string 문자열이 복사되게 하는 DragItem을 반환하는 함수 itemsForBeginning
- import MobileCoreServices 을 추가해주고, 문자열을 .utf8 함수의 반환 인자로 NSItemProvider로 변환되도록 만들어준다
- class UIDragItem : NSObject <- itemsForBeginning의 반환 인자 , NS내용은 오브젝트 C 부분임
extension ViewController: UITableViewDropDelegate{
func tableView(_ tableView: UITableView, performDropWith coordinator: UITableViewDropCoordinator) {
let destinationIndexPath: IndexPath
if let indexPath = coordinator.destinationIndexPath {
destinationIndexPath = indexPath
} else {
let section = tableView.numberOfSections - 1
let row = tableView.numberOfRows(inSection: section)
destinationIndexPath = IndexPath(row: row, section: section)
}
coordinator.session.loadObjects(ofClass: NSString.self) { items in
guard let strings = items as? [String] else { return }
var indexPaths = [IndexPath]()
for(index,string) in strings.enumerated() {
let indexPath = IndexPath(row: destinationIndexPath.row + index, section: destinationIndexPath.section)
if tableView == self.leftTableView{
self.leftItems.insert(string, at: indexPath.row)
}else {
self.rightItems.insert(string, at: indexPath.row)
}
indexPaths.append(indexPath)
}
tableView.insertRows(at: indexPaths, with: .automatic)
}
}
}
- DropDelegate를 이용해 선택된 문자열 data가 추가 되도록 insert함수를 사용
- indexPaths배열에 append를 이용해 추가된 idnexPath 추가