나는 라이브러리를 최대한 사용하지 않으려고 하는 편이다..
아래 첨부한 기능인 Tab Item 전환 기능을 TabMan 라이브러리를 활용하지 않고 구현해보고자 한다.
이번 포스팅에서 다룰 내용은 탭 상단(아이템) 부분 Animation 적용에 대해서만 다룰 예정이다. 각 Tab에 대한 스크롤/페이징 되는 UI는 현재 프로젝트에서 중요성이 떨어지는 부분으로 나중에 시간이 남으면 추가해 보도록 하겠다.
CollectionView 데이터 바인딩은 이미 되어 있다는 가정하에 설명을 진행하도록 하겠다.
changeSelectCell 메서드 내부에서 UI 변경 작업을 진행했다.
아래 작성한 코드에서는 생략했지만 changeSelectCell 메서드 이외에도 처리한 작업들이 있기 때문이다.
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
changeSelectCell(faqId: indexPath.row)
...
}
ServiceTitleCollectionViewCell에 isSelect 프로퍼티를 통해 UI가 변경되도록 구현해놓은 상태이다.
이전에 선택됐었던 Cell은 willSet 감시자를 통해 선택 취소가 되며, 새로 선택된 Cell은 didSet 감시자를 통해 선택 버전의 UI가 적용된다.
private func changeSelectCell(faqId: Int){
selectServiceCell = mainView.serviceCollectionView.cellForItem(at: [0,faqId], cellType: ServiceTitleCollectionViewCell.self)
changeSelectCellUnderLineLayout()
}
private var selectServiceCell: ServiceTitleCollectionViewCell!{
willSet{
selectServiceCell?.isSelect = false
}
didSet{
selectServiceCell.isSelect = true
}
}
/*
ServiceTitleCollectionViewCell의 isSelect 프로퍼티
var isSelect: Bool = false{
didSet{
titleLabel.textColor = isSelect ? UIColor.zatchPurple : .black20
}
}
*/
이 부분이 이번 포스팅의 목적이다.
원래는 Snapkit 라이브러리를 사용하기 때문에 Snapkit 메서드를 최대한 활용하고자 updateConstraints나 remakeConstraints를 활용해 레이아웃을 조정하려고 했었다.
하지만 updateConstraints의 경우 기준이 되는 View를 변경하지 못하고 offset 등의 수치만 변경이 가능하기 때문에 구현하려는 기능에는 적합하지 않다고 판단을 했다.
remakeConstraints를 활용하게 될 경우, 변하지 않는 높이와 하단까지 매번 재설정을 해줘야 하기 때문에 이것도 부적합하다고 판단했다.
구글링을 통해 찾은 해법은 underLineConstraints의 activate, deactivate 메서드를 활용하는 방법이다.
activate 메서드 공식문서를 통해 확인해보면,
Parameters
: An array of constraints to activate.
배열에 activate 할 제약조건을 넣어주면 된다고 나와있다.
즉, 원하는 조건들만 activate, deactivate 하여 레이아웃을 조정할 수 있는 것이다.
구현한 코드를 살펴보겠다.
private var underLineConstraints: [NSLayoutConstraint]!
private func changeSelectCellUnderLineLayout(){
defer {
animateChangeUnderLineLayout()
}
if underLineConstraints != nil {
NSLayoutConstraint.deactivate(underLineConstraints)
}
underLineConstraints = [
selectCellUnderLine.leadingAnchor.constraint(equalTo: selectServiceCell.leadingAnchor),
selectCellUnderLine.trailingAnchor.constraint(equalTo: selectServiceCell.trailingAnchor)
]
NSLayoutConstraint.activate(underLineConstraints)
}
private func animateChangeUnderLineLayout(){
UIView.animate(withDuration: 0.3) {
self.view.layoutIfNeeded()
}
}
최종 구현한 모습이다
@ 참고
enum을 configuration으로 사용할 때 발생하는 안티 패턴 제거해보기 (0) | 2023.12.14 |
---|---|
protocol 상속과 메서드의 매개변수를 사용하여 코드 재사용성 높이기 (0) | 2023.12.09 |
JSON 파일 생성 및 파싱해 프로젝트에서 사용하기 (0) | 2023.04.27 |
Tag DesignSystem 리팩토링 과정 (0) | 2023.03.19 |
Protocol과 상속 관계를 활용해 HeaderView 구성하기 (0) | 2023.02.05 |