본문 바로가기
Project/UIKit 업비트

[UIKit] TableView에서 insetGrouped 스타일로 섹션을 나눠보자

by iOS_woo 2023. 4. 22.

이번에는 TableView의 스타일 중에 하나인 .insetGrouped 를 활용해서 섹션을 나눈 방법에 대해서 기록할게요.
어딘선가 많이 본 스타일이죠?

 

1. TableViewCell을 생성해주세요.

class ProfileCell: UITableViewCell {
    // MARK: - Properties
    
    private let cellLabel: UILabel = {
        let label = UILabel()
        return label
    }()
    
    // MARK: - Lifecycle
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        accessoryType = .disclosureIndicator // 오른쪽 화살표
        
        addSubview(cellLabel)
        cellLabel.centerY(inView: self)
        cellLabel.anchor(left: leftAnchor, paddingLeft: 12)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - Helpers
    
    func configure(with label: String) {
        cellLabel.text = label
    }
}

 

2. TableView에서 사용할 리스트를 생성해주세요.
저는 간단하게 문자 배열로 만들어주었지만, 모델을 만들어서 아이콘 등이 같이 있는 배열을 만들어줄 수도 있어요.

var tableCellList: [String] {
        return ["프로필 사진 변경", "이용약관", "개인정보 처리방침", "건의하기", "로그아웃", "회원탈퇴"]
    }

 

3. viewDidLoad에서 초기 설정을 해주어요.

private let cellIdentifier = "ProfileCell"

tableView = UITableView(frame: tableView.frame, style: .insetGrouped) // 스타일 설정
        
tableView.register(ProfileCell.self, forCellReuseIdentifier: cellIdentifier)

 

4. numberOfSections, numberOfRowsInSection, cellForRowAt 설정을 해주어요.

Switch를 활용해서 섹션마다 셀의 갯수와 셀의 순서를 설정해주어요.

override func numberOfSections(in tableView: UITableView) -> Int {
        return 3
    }

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        switch section {
        case 0:
            return 1
        case 1:
            return 3
        case 2:
            return 2
        default:
            return 0
        }
    }

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! ProfileCell
        switch indexPath.section {
        case 0:
            cell.configure(with: vm.tableCellList[0])
        case 1:
            cell.configure(with: vm.tableCellList[indexPath.row + 1])
        case 2:
            cell.configure(with: vm.tableCellList[indexPath.row + 4])
        default:
            break
        }
        return cell
    }

 

5. ProfileController 전체 코드

import UIKit

private let cellIdentifier = "ProfileCell"
private let headerIdentifier = "ProfileHeader"

class ProfileController: UITableViewController {
    
    // MARK: - Properties
    
    var vm = ProfileViewModel()
    
    // MARK: - Lifecycle
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        configureTableView()
    }
    
    // MARK: - Helpers
    
    func configureTableView() {
        navigationItem.title = "설정"
        view.backgroundColor = .white
        
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "편집",
                                                            style: .plain,
                                                            target: self,
                                                            action: #selector(handleEditProfile))
        navigationItem.rightBarButtonItem?.tintColor = .systemBlue
        
        tableView = UITableView(frame: tableView.frame, style: .insetGrouped)
        
        tableView.register(ProfileCell.self, forCellReuseIdentifier: cellIdentifier)
        tableView.register(ProfileHeader.self,
                           forHeaderFooterViewReuseIdentifier: headerIdentifier)
        tableView.rowHeight = 50
    }
    
    // MARK: - Actions
    
    @objc func handleEditProfile() {
        print("편집 눌렀습니다.")
    }
}

// MARK: - TableViewDataSource

extension ProfileController {
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 3
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        switch section {
        case 0:
            return 1
        case 1:
            return 3
        case 2:
            return 2
        default:
            return 0
        }
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! ProfileCell
        switch indexPath.section {
        case 0:
            cell.configure(with: vm.tableCellList[0])
        case 1:
            cell.configure(with: vm.tableCellList[indexPath.row + 1])
        case 2:
            cell.configure(with: vm.tableCellList[indexPath.row + 4])
        default:
            break
        }
        return cell
    }
}

// MARK: - TableViewDelegate

extension ProfileController {
    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        guard section == 0 else { return nil }
        
        let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: headerIdentifier)
        return header
    }
    
    override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        guard section == 0 else { return 0 }
        
        return 200
    }
}


완성!

애플의 기본 앱, 텔레그램 등 많은 앱에서 볼 수 있는 스타일의 UI가 완성되었어요.
이번 작업을 통해서  UITableView에 대해서 더 공부해볼 수 있었어요.

홧팅~

댓글