관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 커스텀 셀 custom cell (only code) 본문

iOS 응용 (swift)

[iOS - swift] 커스텀 셀 custom cell (only code)

jake-kim 2021. 5. 2. 23:31

 

구성: stackView안에 imageView, label, button

Cell에 매핑될 모델 추가

struct CustomCellModel {
    let leftImage: UIImage
    let leftTitle: String
}

Custom Cell 추가

  • id 정의
class CustomCell: UITableViewCell {
    static let identifier = "CustomCell"
}
  • 나머지 뷰 정의
    • 주의: hugging, compression값 설정 참고
    // CustomCell.swift
    lazy var stackView: UIStackView = {
        let stackView = UIStackView(arrangedSubviews: [leftImageView, leftLabel, rightButton])
        contentView.addSubview(stackView)

        stackView.snp.makeConstraints { (make) in
            make.top.left.bottom.right.equalTo(contentView)
        }
        return stackView
    }()

    lazy var leftImageView: UIImageView = {
        let imageView = UIImageView()
        let image = UIImage(systemName: "star.fill")!
        imageView.image = image
        imageView.setContentHuggingPriority(.required, for: .horizontal)
        imageView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
        imageView.snp.makeConstraints { (make) in
            make.width.equalTo(40)
        }
        return imageView
    }()

    lazy var leftLabel: UILabel = {
        let label = UILabel()
        return label
    }()

    lazy var rightButton: UIButton = {
        let button = UIButton()
        button.setBackgroundImage(UIImage(systemName: "chevron.right"), for: .normal)
        return button
    }()
  • 초기화 코드
    // CustomCell.swift
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        print(stackView)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been impl")
    }
  • 기능: model -> cell 매핑
// CustomCell.swift
    
// MARK: - Utils

extension CustomCell {
    public func bind(model: CustomCellModel) {
        leftImageView.image = model.leftImage
        leftLabel.text = model.leftTitle
    }
}

* CustomCell 전체코드

import UIKit
import SnapKit

class CustomCell: UITableViewCell {

    static let identifier = "CustomCell"

    lazy var stackView: UIStackView = {
        let stackView = UIStackView(arrangedSubviews: [leftImageView, leftLabel, rightButton])
        contentView.addSubview(stackView)

        stackView.snp.makeConstraints { (make) in
            make.top.left.bottom.right.equalTo(contentView)
        }
        return stackView
    }()

    lazy var leftImageView: UIImageView = {
        let imageView = UIImageView()
        let image = UIImage(systemName: "star.fill")!
        imageView.image = image
        imageView.setContentHuggingPriority(.required, for: .horizontal)
        imageView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
        imageView.snp.makeConstraints { (make) in
            make.width.equalTo(40)
        }
        return imageView
    }()

    lazy var leftLabel: UILabel = {
        let label = UILabel()
        return label
    }()

    lazy var rightButton: UIButton = {
        let button = UIButton()
        button.setBackgroundImage(UIImage(systemName: "chevron.right"), for: .normal)
        return button
    }()

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        print(stackView)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been impl")
    }
    
}

// MARK: - Utils

extension CustomCell {
    public func bind(model: CustomCellModel) {
        leftImageView.image = model.leftImage
        leftLabel.text = model.leftTitle
    }
}

TableView에서 CustomCell 사용

  • tableView 생성
  • tableView.register(CustomCell.swlf, forCellReuseIdentifier: CustomCell.identifier)
  • delegate구현
import UIKit

class ViewController: UIViewController {

    private lazy var tableView: UITableView = {
        let tableView = UITableView()
        view.addSubview(tableView)
        tableView.snp.makeConstraints { (make) in
            make.left.right.bottom.equalTo(view)
            make.top.equalTo(view).offset(40)
        }
        return tableView
    }()

    var dataSource = [CustomCellModel]()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        setupView()
        loadData()
    }

    private func setupView() {
        tableView.register(CustomCell.self, forCellReuseIdentifier: CustomCell.identifier)
        tableView.delegate = self
        tableView.dataSource = self
    }

    private func loadData() {
        dataSource.append(.init(leftImage: UIImage(systemName: "pencil")!, leftTitle: "연필"))
        dataSource.append(.init(leftImage: UIImage(systemName: "bookmark.fill")!, leftTitle: "북마크"))
        tableView.reloadData()
    }
}

extension ViewController: UITableViewDelegate, UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataSource.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: CustomCell.identifier) as? CustomCell ?? CustomCell()
        cell.bind(model: dataSource[indexPath.row])
        return cell
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 56
    }
}

 

Comments