해커톤을 위해 토이 프로젝트를 하고 있다.
디자인이 슬슬 나오기 시작한다.
오늘 조진 GUI 화면 구현이 조금 복잡하여 블로그에 정리해보려 한다.
기록하려는 것이기 때문에 설명 불친절 주의☠️
Reusable Horizontal UICollectionView in UITableView
라는 뜻은 아래의 스크린 샷과 같은 UI를 내가 표현해본 것이다.
큰틀로 UITableView를 유지하면서 중간중간 Cell 에 Horizontal 하게 Scroll 될 수 있는 UICollectionView 를 넣어주는 것이다.
처음엔 그냥 UIScrollView 에 UIVIew로 나눠서 하나씩 UICollectionView 를 넣으려 했다. 문제는
생각보다 저 UICollectionView 가 똑같이 사용되는 UI 가 많았다.
이 방식 대론 계속 하나씩 구현해야 되니 눈물을 머금고
UITableView 에 Cell 로 집어 넣기로 한다.
주요 아이디어는 TableView 와 CollectionView 의 Cell을 만들때 Nib 으로 만들고
Cell 안에 CollectionView 관련 메소드를 구현하는 것이다.
#1 ViewController 에 UITableView 를 만들어 준다.
#2 각 UITableViewCell 에 들어갈 Cell 들의 Nib 을 등록한다.
private func setupTableView(){
// Register the xib for tableview cell
tableView.delegate = self
tableView.dataSource = self
// #1
let curatingCellNib = UINib(nibName: "CuratingCell", bundle: nil)
self.tableView.register(curatingCellNib, forCellReuseIdentifier: "CuratingCell")
// #2 #3
let newsLetterCellNib = UINib(nibName: "NewsLetterCell", bundle: nil)
self.tableView.register(newsLetterCellNib, forCellReuseIdentifier: "NewsLetterCell")
// #4
let categoryCellNib = UINib(nibName: "CategoryCell", bundle: nil)
self.tableView.register(categoryCellNib, forCellReuseIdentifier: "CategoryCell")
}
여기서 Nib들은 다 New ->Create Cocoa Touch Class -> ~Cell (with xib) 해서 만들어준 것이다.
그리고 Datasource 와 Delegate 를 Extension 에 적어준다.
extension HomeVC: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
switch indexPath.row {
case 0:
return 270
case 1:
return 270
case 2:
return 270
case 3:
return 300
default:
return 80
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.row {
case 0:
if let cell = tableView.dequeueReusableCell(withIdentifier: "CuratingCell") as? CuratingCell {
cell.lbTitle.text = "에디터 선정 이달의 뉴스레터"
cell.cellDelegate = self
return cell
}
case 1:
if let cell = tableView.dequeueReusableCell(withIdentifier: "NewsLetterCell") as? NewsLetterCell {
cell.lbName.text = "김태형"
return cell
}
case 2:
if let cell = tableView.dequeueReusableCell(withIdentifier: "NewsLetterCell") as? NewsLetterCell {
cell.lbName.text = ""
cell.lbTitle.text = "사람들이 많이보는 뉴스레터"
return cell
}
case 3:
if let cell = tableView.dequeueReusableCell(withIdentifier: "CategoryCell") as? CategoryCell {
return cell
}
default:
return UITableViewCell()
}
return UITableViewCell()
}
}
#3 구현 방식은 curatingCell 과 newsLetterCell, categoryCell 모두 동일하다.
그래서 2번 사용되는 newsLetterCell 만 잡고 정리하자면
TableViewCell 의 Xib를 만들고
UICollectionViewCell 의 Xib 를 만들고
TableViewCell 에 Collection뷰 관련 메소드를 정의해준다.
//
// NewsLetterCell.swift
// TK
//
// Created by TaeHyeong Kim on 2020/08/03.
// Copyright © 2020 TaeHyeong Kim. All rights reserved.
//
import UIKit
import MSPeekCollectionViewDelegateImplementation
class NewsLetterCell: UITableViewCell {
@IBOutlet weak var lbName: UILabel!
@IBOutlet weak var lbTitle: UILabel!
@IBOutlet weak var collectionView: UICollectionView!
let behavior = MSCollectionViewPeekingBehavior()
override func awakeFromNib() {
super.awakeFromNib()
self.collectionView.dataSource = self
self.collectionView.delegate = self
// Register the xib for collection view cell
let cellNib = UINib(nibName: "NewsLetterCollectionCell", bundle: nil)
self.collectionView.register(cellNib, forCellWithReuseIdentifier: "NewsLetterCollectionCell")
behavior.cellSpacing = 8
behavior.cellPeekWidth = 17
behavior.numberOfItemsToShow = 2
collectionView.configureForPeekingBehavior(behavior: behavior)
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
extension NewsLetterCell : UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 4
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "NewsLetterCollectionCell", for: indexPath) as? NewsLetterCollectionCell {
cell.tagListView.removeAllTags()
cell.tagListView.addTags(["Tag1","Tag2","Tag3"])
return cell
}
return UICollectionViewCell()
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
// let cell = collectionView.cellForItem(at: indexPath) as? CuratingCollectionCell
// self.cellDelegate?.collectionView(collectionviewcell: cell, index: indexPath.item, didTappedInTableViewCell: self)
}
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
behavior.scrollViewWillEndDragging(scrollView, withVelocity: velocity, targetContentOffset: targetContentOffset)
}
}
완성이다.
왜 재사용 이냐면 ViewController 에서 UITableView CellForRowAt 을 보면
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.row {
case 0:
if let cell = tableView.dequeueReusableCell(withIdentifier: "CuratingCell") as? CuratingCell {
cell.lbTitle.text = "에디터 선정 이달의 뉴스레터"
cell.cellDelegate = self
return cell
}
case 1:
if let cell = tableView.dequeueReusableCell(withIdentifier: "NewsLetterCell") as? NewsLetterCell {
cell.lbName.text = "김태형"
return cell
}
case 2:
if let cell = tableView.dequeueReusableCell(withIdentifier: "NewsLetterCell") as? NewsLetterCell {
cell.lbName.text = ""
cell.lbTitle.text = "사람들이 많이보는 뉴스레터"
return cell
}
case 3:
if let cell = tableView.dequeueReusableCell(withIdentifier: "CategoryCell") as? CategoryCell {
return cell
}
default:
return UITableViewCell()
}
return UITableViewCell()
}
}
저기 case 1과 2가 같은 걸 볼수 있다.
이제 난 저기에 다른 datasource 만 넣어주면 처음 계획했던 것 처럼 하나씩 추가 안해도 된다.
양 끝에 잘짝 다음 Cell 이 보이는 CollectionView 는 라이브러리를 사용하였다.
'iOS' 카테고리의 다른 글
iOS 앱 이름 한국어 설정 (4) | 2020.08.29 |
---|---|
[Alamofire_5] 이미지 업로드 예제 코드 (0) | 2020.08.28 |
버스탈때 볼 iOS Interview Questions 정리 (0) | 2020.07.22 |
WWDC2020 키노트 후기 (정리) (1) | 2020.06.23 |
GCD : Grand Central Dispatch (0) | 2020.06.16 |
댓글