UIContextualAction, UISwipeActionsConfiguration 두가지에 대해 알아보자
UITableViewDelegate에서 swipe를 입력하면 trailing 과 leading이 생깁니다. leading 은 왼쪽으로 스와이핑 했을때, trailing은 오른쪽으로 스와이핑 했을 때는 나타냅니다.
UIContextualAction : 테이블 row를 swipe 했을 때 보여지는 액션을 말함. ( == 스와이핑 하는 것을 말함 )
UIContextualAction 클로저 형식으로 handler를 통해 행동을 추가 할 수 있다.
스타일을 보면 normal 과 destructive가 있지만 normal을 선택하고, 타이틀에는 표현하고자 하는 것을 적으면 된다.
클로저를 보면 UIContextualAction, UIVIew, 클러저 타입으로 이루어져 있다.
클로저 안에 프린트를 넣어줌으로써 콘솔 창에 표현이고, completion(true)을 한 이유는, 위 사진을 보면 @escaping (Bool) -> Void 라고 되어 있다. 파라미터가 Bool 타입이고 리턴값은 없는 것이기 때문에 completion( ) 안에 Bool 탑인 true를 넣어준다.
그렇다면 true 말고 false를 넣으면 안될까??
false을 넣어도 실행이 된다. ??? 아마도 iOS 11 이전에는 false로 하면 작동하지 않았는데 버그로 간주되어 수정됐다고한다.
(https://developer.apple.com/forums/thread/129420)
// MARK: - UITableViewDelegate
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let action1 = UIContextualAction(style: .normal, title: "1") { action, view, completion in
print("1")
completion(true)
}
}
}
UISwipeActionsConfiguration : tableView의 row를 스와이프 했을때 작동할 액션들 Set모음
즉, 스와이핑 하는 액션을 모아둔 객체라고 생각하면 된다.
action 안을 보면 Set[ ] 으로 이루워져 있다. Set [ ] 안에 만들어둔 action1을 넣으면 완료 된다.
자 이제 완성 됐으니 실행을 하게 되면
참고 ** trailing은 오른쪽으로 스와이핑 하는 것이기 때문에 순서가 반대로 배치되어 있다. **
원래 라면 스와이핑 1, 2 로 표시되어 하지만 trailing 이기 때문에 반대로 표시된다.
그렇다면 1, 2 나오는 부분의 배경 이나 이미지를 바꿀 수 없을까?
당연히 있다!
action 1 과 action 2의 속성을 보면 바꿔 줄 수 있다.
실행해보면
혹시나 스와이핑 기능이 작동하지 않는다면 viewDidload()을 확인해보자
extension으로 델리게이트 활용 할때는 빠뜨지 않았는지 다시 확인해보자 .
전체 코드는 이렇다 .
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
// 테이블을 만들 배열 만들기
var memoArray: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
}
@IBAction func addButtonTapped(_ sender: UIBarButtonItem) {
let alert = UIAlertController(title: "새로운 메모 추가하기 ", message: "새로운 메모를 추가 하시겠습니까?", preferredStyle: .alert)
let success = UIAlertAction(title: "확인", style: .default) { textField in
let textField = alert.textFields?[0].text
print(textField!)
self.memoArray.append(textField!)
self.tableView.reloadData()
}
let cancel = UIAlertAction(title: "취소", style: .cancel) { action in
print("취소버튼이 눌렸습니다.")
}
alert.addAction(success)
alert.addAction(cancel)
alert.addTextField { textfield in
textfield.placeholder = "메모를 입력해주세요"
}
// 실제 띄우기
self.present(alert, animated: true, completion: nil)
}
}
// MARK: - UITableViewDataSource
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return memoArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "toCell", for: indexPath) as! MyTableViewCell
cell.mainLabel.text = memoArray[indexPath.row]
cell.selectionStyle = .none
return cell
}
}
// MARK: - UITableViewDelegate
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let action1 = UIContextualAction(style: .normal, title: "1") { action, view, completion in
print("오른쪽으로 스와이핑 됐음 1")
completion(true)
}
let action2 = UIContextualAction(style: .normal, title: "2") { action, view, completion in
print("오른쪽으로 스와이핑 됐음 2")
completion(true)
}
action1.backgroundColor = .red
action1.image = UIImage(systemName: "trash")
action2.backgroundColor = .blue
action2.image = UIImage(systemName: "square.and.arrow.up")
return UISwipeActionsConfiguration(actions: [action1, action2])
}
}