UITableViewCell에 Swipe 기능 추가하기

marisol👩🏻‍💻·2022년 6월 23일
1

아이폰 기본 어플인 메모나 알람에서 오른쪽에서 왼쪽으로 swipe하면 공유/삭제 할 수 있는 버튼이 나타나는데,
이번 프로젝트에서 적용해야해서 아래와 같이 뷰를 구현해보고 Action도 연결해볼거다.


📝 UISwipeActionsConfiguration

테이블 뷰의 각 cell에 Swipe해서 Action을 설정하려면, UITableViewDelegate에 있는
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? 메서드를 사용하면 된다.

메서드 이름 상당히 길지만.. 중간에 trailingSwipeActions~~ 이 부분을 보면, 어떤 cell을 trailing swipe(오른쪽 -> 왼쪽) 했을 때의 action을 정해주는 메서드라고 생각하면 될 것 같다. 지금 사용할 메서드는 trailing이니까 당연히 leading 메서드도 따로 있다. leading을 설정해주면 왼쪽 -> 오른쪽으로 swipe 했을 때 Action들이 왼쪽에 생길 것 같다.

이 메서드는 UISwipeActionsConfiguration?을 반환하는데, 이 클래스의 정의는 "테이블의 row(행)을 스와이프할 때 수행할 action의 집합 (set)"이라고 되어 있다.
그래서 trailing 메서드 안에서 이 UISwipeActionsConfiguration?라는 set 안에 들어갈 원하는 action들을 추가해주고 리턴해주면 끝!인듯하다.

📝 UIContextualAction

UISwipeActionsConfiguration?에 추가될 action들은 UIContextualAction 타입으로 생성한다.

UIContextualAction이라는 다소 와닿지 않는 네이밍이지만, 정의를 보면 "사용자가 테이블의 row(행)을 스와이프 할 때 표시할 작업(action)"이라고 나와있다.

👩🏻‍💻 구현해보기

나는 공유랑 삭제 action을 추가할거니까, 아래와 같이 2개의 UIContextualAction을 선언해주었다.

func tableView(_ tableView: UITableView, 
			  trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) 
              -> UISwipeActionsConfiguration? {
              
              let share = UIContextualAction(style: .normal, title: "") { (_, _, success: @escaping (Bool) -> Void) in
              // 원하는 액션 추가
              	let shareActivity = UIActivityViewController(activityItems: [diary], applicationActivities: nil)
                
                self.present(shareActivity, animated: true)
                success(true)
              }
              
              let delete = UIContextualAction(style: .normal, title: "") { (_, _, success: @escaping (Bool) -> Void) in
              	// 원하는 액션 추가
                tableView.deleteRows(at: [indexPath], with: .fade)
                success(true)
              }
              
              // 각 ContextualAction 대한 설정
              share.backgroundColor = .systemBlue
              share.image = UIImage(systemName: "square.and.arrow.up")
              delete.backgroundColor = .systemRed
              delete.image = UIImage(systemName: "trash.fill")
              
              // UISwipeActionsConfiguration에 action을 추가하여 리턴
              return UISwipeActionsConfiguration(actions: [delete, share])
     }
}

UIContextualAction의 handler 부분을 보면 파라미터가 3개나 있는데, 각각 UIContextualAction, UIView, @escaping (Bool) -> Void -> Void 타입이다.

Contextual closure type '(UIContextualAction, UIView, @escaping (Bool) -> Void) -> Void' expects 3 arguments

여기서는 첫번째와 두번째 파라미터는 쓰이지 않아서 "_"로 대체했고, @escaping closure만 true로 설정해주었다.

그리고 마지막에 리턴할 때 set 내부의 ContextualAction의 순서가 [delete, share] 이렇게 되어있는데
trailing 기준이라서 그런지 이렇게 해야 share -> delete의 순서로 나오게 된다.


참고자료

0개의 댓글