본문 바로가기

IOS

Swift - UITableView + ListClick

오늘은 테이블뷰에 간단하게 클릭 이벤트를 줄예정이다.

테이블뷰를 가지고있는 팝업을 띄워 각각의 리스트는 오직 하나의 아이템만 클릭할수 있게 만들어놨다.

해당 아이템은 다시 클릭하면 해제 할수 있게 만들어 일반적으로 떠오르는 팝업형 리스트뷰를 만들어보자.

결과 먼저 보고 들어가겠습니다..

기본적인 테이블뷰 구성하는 부분은 제외 했습니다.


1. 결과

무지성 디자인 무시 바립니다


2. TableViewController

import UIKit
import RxSwift
import RxCocoa
import RxGesture

protocol TableViewDelegate {
    func selectSnack(snack : String)
}

class TableViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    let array = ["포카칩","콘칩","새우깡","감자깡","프링글스"]
    let disposebag = DisposeBag()
    var value = ""
    var tableViewDelegate : TableViewDelegate?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        tableView.register(UINib(nibName: "ListItemCell", bundle: nil), forCellReuseIdentifier: "ListItemCell")
        
        initTableView()
    }
    
    func initTableView() {
        
        Observable.of(array)
            .asObservable()
            .bind(to: tableView.rx.items(cellIdentifier: "ListItemCell", cellType: ListItemCell.self)) {
                [self] index, item, cell in
                
                cell.cellLabel.text = item
                
                if value == item {
                    tableView.selectRow(at: IndexPath(row: index, section: 0), animated: false, scrollPosition: .none)

                } else {
                    tableView.deselectRow(at: IndexPath(row: index, section: 0), animated: false)

                }
                
                cell.cellContentView.rx.tapGesture()
                    .when(.recognized)
                    .subscribe(onNext : {
                        [self] _ in
                        
                        if cell.isSelected {
                            tableView.deselectRow(at: IndexPath(row: index, section: 0), animated: false)
                            value = ""
                        } else {
                            tableView.selectRow(at: IndexPath(row: index, section: 0), animated: false, scrollPosition: .none)

                            value = item
                        }
                        
                    }).disposed(by: cell.cellDisposebag)
                
            }.disposed(by: disposebag)
    }

    @IBAction func snackClick(_ sender: UIButton) {
        tableViewDelegate?.selectSnack(snack: value)
        dismiss(animated: true, completion: nil)
    }
}

테이블뷰의 생성은 RxCocoa 로 처리하였습니다.

팝업을 초기에 띄우고 테이블뷰를 생성할때 뷰 컨트롤러 상에서 넘겨준값과 아이템을 비교하여 셀 선택 여부를 따집니다.

그리고 리스트(UIView) 클릭시 테이블뷰 선택 여부를 다시 설정합니다.

선택 완료후 데이터값은 delegate 패턴을 이용하여 초기 뷰에 보냅니다.


3. listItemCell

import Foundation
import UIKit
import RxSwift

class ListItemCell : UITableViewCell {
    var cellDisposebag = DisposeBag()
    
    @IBOutlet weak var cellContentView: UIView!
    @IBOutlet weak var cellLabel: UILabel!
    
    override func awakeFromNib() {
           super.awakeFromNib()
       }
    
    override func prepareForReuse() {
        cellDisposebag = DisposeBag()
    }
    
    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        
        if selected {
            cellContentView.backgroundColor = UIColor.yellow
        } else {
            cellContentView.backgroundColor = UIColor.white
        }
   }
}

리스트 선택시에 셀의 뷰 색상을 변경합니다


4. ViewController

import UIKit
import RxSwift
import RxCocoa
import RxGesture

class ViewController: UIViewController {

    
    @IBOutlet weak var snackResultLabel: UILabel!
    var tableViewController = TableViewController()
    var selectValue = ""
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func showPopup(_ sender: UIButton) {
        
        guard let tableViewController = self.storyboard?.instantiateViewController(withIdentifier: "TableViewController") as? TableViewController else {
                return
            }
        
        tableViewController.modalPresentationStyle = .currentContext
        tableViewController.view.isOpaque = false
        tableViewController.tableViewDelegate = self
        tableViewController.value = selectValue
        self.present(tableViewController, animated: true, completion: nil)
        
    }
}

extension ViewController : TableViewDelegate {
    func selectSnack(snack: String) {
        selectValue = snack
        snackResultLabel.text = snack.isEmpty ? "선택한 과자 없음" : "선택한 과자는 : \(snack)"
    }
}

팝업을 띄울때마다 현재 저장되어있는 값을 보내고 팝업상에서 보내준 값은 delegate 패턴을 이용해 받습니다.

'IOS' 카테고리의 다른 글

Swift - TextView PlaceHolder  (0) 2021.08.26
Swift - Combine VS RxSwift  (0) 2021.08.21
Swift - Property Wrapper  (0) 2021.08.06
Swift - Reactive Programming (Rx)  (0) 2021.08.02
Swift - ReactorKit / ErrorHandling  (0) 2021.07.24