본문 바로가기

개발/Swift

[Swift/SPM] SwipeCellKit으로 스와이프로 삭제하는 기능 추가, VC간 공유하기 (with. Realm)

DB는 Realm, 스와이프 라이브러리는 SwipeCellKit 을 사용하여 작업한 코드입니다.

둘다 Swift Package Manager으로 설치하여 사용했습니다. (cocoapods로 해도 다른건 없지만,,)

 

 

 

SwipeCellKit Github

 

GitHub - SwipeCellKit/SwipeCellKit: Swipeable UITableViewCell/UICollectionViewCell based on the stock Mail.app, implemented in S

Swipeable UITableViewCell/UICollectionViewCell based on the stock Mail.app, implemented in Swift. - GitHub - SwipeCellKit/SwipeCellKit: Swipeable UITableViewCell/UICollectionViewCell based on the s...

github.com


적용할 기능 예시

SwipeViewController를 만들어 Swipe기능을 사용할 TableViewController에 상속하여 불필요한 코드를 줄이려고 합니다.

우선 SwipeTableViewController.swift 를 만들고 SwipeCellKit을 import 해줍니다..

import UIKit
import SwipeCellKit

class SwipeTableViewController: UITableViewController, SwipeTableViewCellDelegate {
    // 앞으로 기재할 곳
}

우선 재사용셀을 정의 하고 우리가 사용할 셀의 형태인 SwipeTableViewCell 으로 다운캐스팅합니다.

그리고 이 Cell의 상태에 대해 보고받기 위해 delegate 위치를 지정해줍니다.

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! SwipeTableViewCell
    cell.delegate = self // SwipeTableViewCellDelegate 보고하는 곳 설정
    return cell
}

그 다음은 SwipeTableViewCellDelegate에 해당하는 editActionsForRowAt 메소드 부분입니다.
이 메소드는 스와이프를 하면 호출되며 Delete버튼을 누르면 deleteAction 프로퍼티가 호출됩니다.

deleteAction 프로퍼티에 해당 셀을 제거하는 내용이 들어가야하기 때문에 이 부분을 해당 indexPath를 받는 메소드(updateDelete)를 호출하도록 합니다.

updateDelete 메소드는 이 뷰컨트롤러를 상속받는 ViewController에서 override 해줄겁니다.

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]? {
    guard orientation == .right else { return nil }
    print("Swipe Called")

    let deleteAction = SwipeAction(style: .destructive, title: "삭제하기") { action, indexPath in
        self.updateDelete(indexPath: indexPath) // Delete 명령이 들어갈 곳.
                print("Cell is Deleted")

    }
    deleteAction.image = UIImage(named: "trash.fill")
    return [deleteAction]
}

 //MARK: Swipe 길게하여 삭제하는 부분. 따로 스타일을 바꿀것이 아니라면 공식 문서에 정의되어있는 그대로 둡니다.
    func tableView(_ tableView: UITableView, editActionsOptionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> SwipeOptions {
        print("Swipe Option Called")
                var options = SwipeOptions()
        options.expansionStyle = .destructive
        options.transitionStyle = .border
        return options
}

SwipeTableViewController의 전체코드

//
//  SwipeTableViewController.swift
//

import UIKit
import SwipeCellKit

class SwipeTableViewController: UITableViewController, SwipeTableViewCellDelegate {

    // MARK: - Table view DataSource - 공통된 부분 정의하고 Cell을 SwipeTableViewCell로 다운캐스팅
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! SwipeTableViewCell
        cell.delegate = self // SwipeTableViewCellDelegate 보고하는 곳 설정
        return cell
    }

    //MARK: - Swipe Data Delegate 정의
    //MARK: Swipe 했을때 동작
    func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]? {
        guard orientation == .right else { return nil }

        let deleteAction = SwipeAction(style: .destructive, title: "Delete") { action, indexPath in
            self.updateDelete(indexPath: indexPath) // Delete 명령이 들어갈 곳.
            print("Swipe Button Delete Called")
        }
        deleteAction.image = UIImage(named: "trash.fill")

        return [deleteAction]
    }

    //MARK: Swipe로 삭제하기.
    func tableView(_ tableView: UITableView, editActionsOptionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> SwipeOptions {
        var options = SwipeOptions()
        options.expansionStyle = .destructive
        options.transitionStyle = .border
        print("Swipe Option Called")
        return options
    }

    //MARK: 삭제 할 행 업데이트하기
    func updateDelete(indexPath: IndexPath) {
        // 여기에 삭제할 행 및 삭제 명령이 들어갑니다.
        // SwipeTableViewController를 상속할 ViewController에서 override 하여 작성 
    }
}

스와이프 기능을 넣을 ViewController에서 작업하기

//
// TableViewController.swift
//

import UIKit
import RealmSwift
class TableViewController: SwipeTableViewController {

    //...

    // 1번 부분
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = super.tableView(tableView, cellForRowAt: indexPath)
        cell.textLabel?.text = categoryArray?[indexPath.row].name
        return cell
    }

    // 2번 부분
    override func updateDelete(indexPath: IndexPath) {
      if let item = self.itemArray?[indexPath.row] {
          do {
              try realm.write({
                  realm.delete(item)
              })
          } catch {
              print("update Error : \(error)")
          }
      }

  }
    // ...

}

코드의 1번 부분에서는 우리가 위에서 정의한 슈퍼뷰의 재사용 셀 및 delegate에 대한 내용을 상속하고 표시할 데이터를 정의해주었습니다. (여기서는 categoryArray에 있는 name 프로퍼티)

이렇게 표시될 예정

코드의 2번부분은 앞에서 정의한 updateDelete 이며 이 부분에서 선택된 categoryArray[indexPath.row]의 내용을 삭제할거에요.

이 부분만 override 하면 나머지 내용은 이미 정의해두었기 때문에 Swipe로 삭제하는 기능이 동작하게 됩니다.

이제 앞으로 TableView를 사용할 때 Swipe 기능을 사용하려면 SwipeTableViewController 를 슈퍼클래스로 상속 후

1번, 2번 부분만 오버라이딩 하면 스와이프 기능을 사용 가능합니다. 👏👏👏

 

 

참고 - iOS & Swift - The Complete iOS App Development Bootcamp by Dr. Angela Yu (Udemy)

 

 

 

 

반응형