본문 바로가기
YAGOM CAREER STARTER

[TIL] 20230223: TableView 코드로 구현하기

by Rhode 2023. 2. 24.

본문은 야곰 아카데미 커리어 스타터 캠프를 통해 학습한 내용을 회고한 글입니다.


TableView 코드로 구현하기

오늘은 테이블뷰를 코드로 구현하는 것을 해보겠다.

위와 같은 테이블 뷰를 구성한 코드를 보여줄 것이다.

 

첫번째 뷰 컨트롤러다:

import UIKit

class ListViewController: UIViewController {

    let listTableView: UITableView = {
        let tableView = UITableView(frame: .zero, style: .grouped)
        tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: CustomTableViewCell.identifier)
        tableView.translatesAutoresizingMaskIntoConstraints = false

        return tableView
    }()

    let listCell: CustomTableViewCell = {
        let cell = CustomTableViewCell()
        
        return cell
    }()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        view.addSubview(listTableView)
        
        configureTableView()
    }

    private func configureTableView() {
        let safeArea = view.safeAreaLayoutGuide
        
        listTableView.delegate = self
        listTableView.dataSource = self
        
        NSLayoutConstraint.activate([
            listTableView.topAnchor.constraint(equalTo: safeArea.topAnchor),
            listTableView.leadingAnchor.constraint(equalTo: safeArea.leadingAnchor),
            listTableView.trailingAnchor.constraint(equalTo: safeArea.trailingAnchor),
            listTableView.bottomAnchor.constraint(equalTo: safeArea.bottomAnchor)
        ])
    }
}

extension ListViewController: UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return 3
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 3
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: CustomTableViewCell.identifier) as? CustomTableViewCell else {
            return CustomTableViewCell()
        }
        cell.configure(index: indexPath.row)

        return cell
    }
    
    
}

extension ListViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return UITableView.automaticDimension
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let detailViewController: DetailViewController = DetailViewController()
        
        navigationController?.pushViewController(detailViewController, animated: true)
        tableView.deselectRow(at: indexPath, animated: true)
    }
}

 

 

커스텀 테이블뷰 셀이다:

import UIKit

class CustomTableViewCell: UITableViewCell {
    
    let contentHorizontalStackView: UIStackView = {
        let stackView = UIStackView()
        
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.axis = .horizontal
        stackView.alignment = .center
        stackView.distribution = .fill
        stackView.spacing = 10
        
        return stackView
    }()
    
    let listImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.image = UIImage(named: "princess_red_saphire")
        
        return imageView
    }()
    
    let contentVerticalStackView: UIStackView = {
        let stackView = UIStackView()
        
        stackView.axis = .vertical
        stackView.alignment = .leading
        stackView.distribution = .equalSpacing
        stackView.spacing = 10
        
        return stackView
    }()
    
    let titleLabel: UILabel = {
        let label = UILabel()
        
        label.text = "제품이름"
        label.font = UIFont.preferredFont(forTextStyle: .title3)
        
        return label
    }()
    
    let subtitleLabel: UILabel = {
        let label = UILabel()
        
        label.text = "설명"
        label.font = UIFont.preferredFont(forTextStyle: .body)
        
        return label
    }()
    
    func configure(index: Int) {
        contentView.addSubview(contentHorizontalStackView)
        NSLayoutConstraint.activate([
            contentHorizontalStackView.topAnchor.constraint(equalTo: contentView.topAnchor),
            contentHorizontalStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
            contentHorizontalStackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
            contentHorizontalStackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
        ])
        
        configureVerticalStackView()
        configureHorizontalStackView()
        configureImageView(index: index)
    }
    
    private func configureHorizontalStackView() {
        self.contentHorizontalStackView.addArrangedSubview(listImageView)
        self.contentHorizontalStackView.addArrangedSubview(contentVerticalStackView)
        
    }
    
    private func configureImageView(index: Int) {
        NSLayoutConstraint.activate([
            listImageView.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: 0.3),
            listImageView.heightAnchor.constraint(equalTo: listImageView.widthAnchor, multiplier: 1.0)
        ])
    }
    
    private func configureVerticalStackView() {
        self.contentVerticalStackView.addArrangedSubview(titleLabel)
        self.contentVerticalStackView.addArrangedSubview(subtitleLabel)
    }
}

 

하면서 가장 많이 마주했던 오류는 constraint와 관련한 오류였다.

그럴 때 생각해보아야할 것들은 다음과 같다:

  • constraint를 잡고 있는 것은 맞는가
  • 내가 UI를 addSubView 안 한채로 constraint를 잡진 않았는가
  • SuperView 등이 먼저 호출되고 있는 것은 맞는가(코드의 순서)

이 안에서 보통 문제가 해결되는 편이었다.

'YAGOM CAREER STARTER' 카테고리의 다른 글

[토요스터디A반] 20230225: TableView  (0) 2023.02.27
[TIL] 20230224: Initializer  (0) 2023.02.24
[TIL] 20230220: JSON  (0) 2023.02.21
[TIL] 20230207: Decimal, Closures  (0) 2023.02.08
[TIL] 20230206: 메모리, ARC  (3) 2023.02.07