[Swift] TagListView 만들기 - 라이브러리 활용

선주·2023년 1월 13일
0

Swift

목록 보기
20/20

안녕하세요 🤩 지난 포스팅에서는 요렇게 동작하는 TagListView를 UIButton으로 직접 구현해보았는데, 이번 포스팅에서는 오픈소스 라이브러리를 활용하여 더 간단하게 만들어보겠습니다! 움짤도 해당 라이브러리를 이용해 구현한 모습입니다 👍

  • 태그 중복 선택 불가
  • 태그가 선택된 상태라면 태그의 테두리, 텍스트, 좌측의 필터 이미지를 컬러링해줄 것
  • 선택된 태그를 다시 클릭하면 선택이 해제될 것



🗒 pod 'TagListView'

위 라이브러리를 활용해보겠습니다. 클릭하면 Github로 이동합니다!

podfile을 열어 pod 'TagListView 라인을 추가한 후 pod install을 진행합니다. 또는 SPM으로 TagListView를 설치해줍니다.




🎨 Storyboard

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의 높이를 계산하여 적용해주어야 합니다.




참고
Github Issue | anelad's answer

profile
기록하는 개발자 👀

0개의 댓글