(iOS) TTGTagCollectionView 라이브러리 공부하기
최근에 태그와 관련한 UI를 구성하는 요구사항이 있었는데, 현직자분이 해당 라이브러리를 추천해주셔서 적용해보려고 한다.
UICollectionView로도 충분히 구현할 수 있지만, 현업에서는 오픈소스를 활용한다고 한다.
오픈소스를 코드를 읽고 분석하며 이를 프로젝트 형태에 맞게 적용하는 것 또한 중요하다고 해서 사용하면서 배워보고자 한다.
SPM을 공식적으로 지원하지 않아서 CocoaPod를 통해서 사용하는게 더 편하다.
SPM쓰려면 직접 Package를 배포해야하는데, 이 부분은 아직 잘 모르겠다.
오픈소스 링크
https://github.com/zekunyan/TTGTagCollectionView
GitHub - zekunyan/TTGTagCollectionView: Useful for showing text or custom view tags in a vertical or horizontal scrollable view
Useful for showing text or custom view tags in a vertical or horizontal scrollable view and support Autolayout at the same time. It is highly customizable that most features of the text tag can be ...
github.com
가능한 UI의 예제를 제안해주는데, 눈에 잘 보여서 좋다.

내가 필요한 부분은 좌우로 쭉 늘어나는 태그인데, 아래처럼 구성해보았다.

코드는 생각보다 간편한데, 아래를 보자.
태그를 만드는 코드
//
// NewsListTableViewHeaderView.swift
// KeywordNews
//
// Created by Hamlit Jason on 2022/02/05.
//
import UIKit
import SnapKit
import TTGTags
protocol NewsListTableViewHeaderViewDelegate: AnyObject {
func didSelectTag(_ selectedIndex: Int)
}
final class NewsListTableViewHeaderView: UITableViewHeaderFooterView {
static let identifier = "NewsListTableViewHeaderView"
private lazy var tagCollectionView = TTGTextTagCollectionView()
private weak var delegate: NewsListTableViewHeaderViewDelegate?
private var tags: [String] = []
func setup(
tags: [String],
delegate: NewsListTableViewHeaderViewDelegate
) {
self.tags = tags
self.delegate = delegate
contentView.backgroundColor = .systemBackground
setupTagCollectionViewLayout()
setupTagCollectionView()
}
}
extension NewsListTableViewHeaderView: TTGTextTagCollectionViewDelegate {
func textTagCollectionView(_ textTagCollectionView: TTGTextTagCollectionView!, didTap tag: TTGTextTag!, at index: UInt) {
print("textTagCollectionView \(tag)")
guard tag.selected else { return } // 태그가 셀렉 되었을 때만 불려지게끔 필터링 해주기 -> 태그가 셀렉되지 않은 상태로 조건이 변경될 때도 불려지기 때문에
delegate?.didSelectTag(Int(index))
}
func textTagCollectionView(_ textTagCollectionView: TTGTextTagCollectionView!, canTap tag: TTGTextTag!, at index: UInt) -> Bool {
print("canTap")
return true
}
}
private extension NewsListTableViewHeaderView {
func setupTagCollectionViewLayout() {
addSubview(tagCollectionView)
tagCollectionView.snp.makeConstraints {
$0.edges.equalToSuperview()
}
}
func setupTagCollectionView() {
tagCollectionView.delegate = self
tagCollectionView.numberOfLines = 1
tagCollectionView.scrollDirection = .horizontal
tagCollectionView.showsVerticalScrollIndicator = false
tagCollectionView.selectionLimit = 1
let insetValue: CGFloat = 16.0
tagCollectionView.contentInset = UIEdgeInsets(
top: insetValue,
left: insetValue,
bottom: insetValue,
right: insetValue
)
let cornerRadiusValue: CGFloat = 12.0
let shadowOpacity: CGFloat = 0.0
let extraSpace = CGSize(width: 20.0, height: 12.0)
let color = UIColor.systemOrange
let style = TTGTextTagStyle()
style.backgroundColor = color
style.cornerRadius = cornerRadiusValue
style.borderWidth = 0.0
style.shadowOpacity = shadowOpacity
style.extraSpace = extraSpace
let selectedStyle = TTGTextTagStyle()
selectedStyle.backgroundColor = .white
selectedStyle.cornerRadius = cornerRadiusValue
selectedStyle.shadowOpacity = shadowOpacity
selectedStyle.extraSpace = extraSpace
selectedStyle.borderColor = color
tags.forEach { tag in
let font = UIFont.systemFont(ofSize: 14.0, weight: .semibold)
let tagContents = TTGTextTagStringContent(
text: tag,
textFont: font,
textColor: .white
)
let selectedTagContents = TTGTextTagStringContent(
text: tag,
textFont: font,
textColor: color
)
let tag = TTGTextTag(
content: tagContents,
style: style,
selectedContent: selectedTagContents,
selectedStyle: selectedStyle
)
tagCollectionView.addTag(tag)
}
}
}
태그를 만들었다.
이제는 태그를 테이블 뷰의 헤더로 넣어야 한다.
// 헤더등록 코드가 조금 다르다.
tableView.register(
NewsListTableViewHeaderView.self,
forHeaderFooterViewReuseIdentifier: NewsListTableViewHeaderView.identifier
)
태그를 헤더로 넣었으면, 아이디를 등록해준다.
태그는 View이지만 id 등록이 필요하다.
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = tableView.dequeueReusableHeaderFooterView(
withIdentifier: NewsListTableViewHeaderView.identifier
) as? NewsListTableViewHeaderView
header?.setup(tags: tags, delegate: self)
return header
}
기본적으로 테이블 뷰 헤더와 푸터는 딜리게이트의 해당 메서드를 통해서 구현할 수 있다.
'apple > iOS, UIKit, Documentation' 카테고리의 다른 글
| iOS Lottie 알아보기 (.json, .lottie) (0) | 2022.02.19 |
|---|---|
| Showing All Messages Undefined symbol: __swift_FORCE_LOAD_$_XCTestSwiftSupport (0) | 2022.02.18 |
| Swift Protocol (@objc, extension 기본 구현) (0) | 2022.01.31 |
| iOS Starscream 총정리 (0) | 2022.01.12 |
| iOS Snapkit 나만의 정리 모음 (5) | 2021.08.25 |