오늘은 UITableVIew에 Header를 만드는 방법을 기록할거에요.
사진 속에서 프로필 사진, 이름, 전화번호, 유저아이디가 있는 영역이 오늘 작업할 Header에요.
1. ProfileHeader를 만들어주세요.
class ProfileHeader: UITableViewHeaderFooterView {
// MARK: - Properties
var vm: ProfileHeaderViewModel? {
didSet { configure() }
}
private let profileImageView: UIImageView = {
let iv = UIImageView()
iv.contentMode = .scaleAspectFill
iv.clipsToBounds = true
iv.backgroundColor = .lightGray
iv.image = UIImage(named: "venom-7")
return iv
}()
private let nameLabel: UILabel = {
let label = UILabel()
label.font = UIFont.boldSystemFont(ofSize: 20)
label.text = "Woo"
return label
}()
private let phoneNumberLabel: UILabel = {
let label = UILabel()
label.font = UIFont.systemFont(ofSize: 14)
label.text = "+82 10 9650 3650"
label.textColor = .lightGray
return label
}()
private let userIdLabel: UILabel = {
let label = UILabel()
label.font = UIFont.systemFont(ofSize: 14)
label.text = "@minwoo_smile"
label.textColor = .lightGray
return label
}()
// MARK: - Lifecycle
override init(reuseIdentifier: String?) {
super.init(reuseIdentifier: reuseIdentifier)
configureUI()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
// MARK: - Helpers
func configureUI() {
addSubview(profileImageView)
profileImageView.centerX(inView: self)
profileImageView.setDimensions(height: 100, width: 100)
profileImageView.anchor(top: topAnchor, paddingTop: 16)
profileImageView.layer.cornerRadius = 100 / 2
addSubview(nameLabel)
nameLabel.centerX(inView: self)
nameLabel.anchor(top: profileImageView.bottomAnchor, paddingTop: 12)
let stack = UIStackView(arrangedSubviews: [phoneNumberLabel, userIdLabel])
stack.axis = .horizontal
stack.spacing = 4
addSubview(stack)
stack.centerX(inView: self)
stack.anchor(top: nameLabel.bottomAnchor, paddingTop: 10)
}
func configure() {
// 작업 예정..
}
}
2. viewDidLoad에서 register 해주세요.
private let headerIdentifier = "ProfileHeader"
tableView.register(ProfileHeader.self,
forHeaderFooterViewReuseIdentifier: headerIdentifier)
3. viewForHeaderInSection, heightForHeaderInSection를 설정해주세요.
guard 문의 코드는 테이블 뷰의 0번째 섹션 위에만 헤더를 놓기 위한 코드에요.
적어주지 않으면 모든 섹션 위에 헤더가 생성되어요.
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
}
4. 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
}
}
완성!
UICollectionView에서 헤더를 생성하는 것도 비슷하게 할 수 있어요.
다음 글에서는 위의 사진처럼 테이블뷰에 섹션을 구분하는 방법을 기록해볼게요.
홧팅~
'Project > UIKit 업비트' 카테고리의 다른 글
[UIKit] UIMenu로 메뉴를 만들어보자 (0) | 2023.04.27 |
---|---|
[UIKit] TableView에서 insetGrouped 스타일로 섹션을 나눠보자 (0) | 2023.04.22 |
[UIKit] UISearchController, 검색 기능 구현하기 (1) | 2023.04.17 |
[UIKit] 업비트 API로 CollectionView에 리스트 만들기 feat.RxCocoa (0) | 2023.04.13 |
[UIKit] CollectionView가 먼저 생성되고 데이터가 갱신되지 않는 문제 (0) | 2023.04.07 |
댓글