안녕하세요 🤩 지난 포스팅에서는 요렇게 동작하는 TagListView를 UIButton으로 직접 구현해보았는데, 이번 포스팅에서는 오픈소스 라이브러리를 활용하여 더 간단하게 만들어보겠습니다! 움짤도 해당 라이브러리를 이용해 구현한 모습입니다 👍
위 라이브러리를 활용해보겠습니다. 클릭하면 Github로 이동합니다!
podfile을 열어 pod 'TagListView
라인을 추가한 후 pod install
을 진행합니다. 또는 SPM으로 TagListView를 설치해줍니다.
TagListView가 삽입될 공간을 UIView로 만들고 Constraints를 잡아줍니다. 그리고 Identify Inspector
창에서 커스텀클래스에 TagListView를 지정해주었습니다.
TagListView를 지정한 후 Attributes Inspector
창을 열면 아래와 같이 태그의 속성들을 스토리보드상에서 쉽게 설정할 수 있습니다. 저는 textColor, selectedTextColor, borderColor, selectedBorderColor, borderWidth, cornerRadius, backgroundColor, padding, margin을 설정해주었습니다.
마지막으로, SearchViewController로 IBOutlet을 세 개 연결해줍니다.
@IBOutlet weak var tagListView: TagListView!
@IBOutlet weak var tagListViewHeight: NSLayoutConstraint!
@IBOutlet weak var filterImageView: UIImageView!
import UIKit
import TagListView
class SearchViewController: UIViewController {
@IBOutlet weak var tagListView: TagListView!
@IBOutlet weak var tagListViewHeight: NSLayoutConstraint!
@IBOutlet weak var filterImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
initTagListView()
}
/// 태그뷰 초기화
private func initTagListView() {
tagListView.delegate = self
tagListView.textFont = UIFont(name: "Pretendard-Medium", size: 12)!
tagListView.alignment = .left
tagListView.addTags(["주차 가능한 절".localized, "반려동물 동반 가능한 절".localized, "요즘 인기 있는 절".localized, "세계 문화 유산에 등재된 절".localized, "경기도에 있는 절".localized, "체험 가능한 절".localized])
tagListViewHeight.constant = tagListView.height
}
}
// MARK: - TagListView
extension SearchVC: TagListViewDelegate {
func tagPressed(_ title: String, tagView: TagView, sender: TagListView) {
// ① 태그 선택 여부 반전
tagView.isSelected = !tagView.isSelected
// ② 태그 하나만 선택할 수 있도록 함
sender.tagViews.filter { $0 != tagView }.forEach { $0.isSelected = false }
// ③ 필터 이미지 색 변경
filterImageView.image = tagView.isSelected ? UIImage(named: "icon_filter") : UIImage(named: "icon_filter_gray")
}
}
extension TagListView {
var height: CGFloat { // ④
let count = CGFloat(self.subviews.count)
let height = self.subviews.first?.frame.height ?? 0
let margin = self.marginY
return CGFloat((count * height) + (count == 0 ? count : count - 1) * margin)
}
}
지난번 직접 구현보다는 코드가 매우 간결해졌습니다.
① tagListView의 delegate를 설정해주고,tagPressed
메소드 내에서 태그가 눌렸을 때 태그의 선택여부만 반전시켜주면 태그의 borderColor, textColor는 아까 스토리보드에서 설정했던 색으로 전환됩니다.
② 또한 우리의 태그는 중복선택이 불가능하기 때문에 태그 하나가 선택되면 나머지 태그들은 미선택상태로 바꿔주어야 합니다. filter를 사용해서 터치된 태그가 아닌 다른 태그들의 상태를 바꿔줍니다.
③ 그리고 모든 태그 중 하나라도 선택된 태그가 있으면 태그필터이미지를 컬러링시켜줍니다.
④ 마지막으로, 태그의 갯수에 따라 tagListView가 몇 줄짜리가 될 지가 달라집니다. 즉, tagListView의 높이를 계산하여 적용해주어야 합니다.