https://soo-hyn.tistory.com/124
Today I Learn(3): 동적으로 뷰 추가 및 삭제
보호되어 있는 글입니다. 내용을 보시려면 비밀번호를 입력하세요.
soo-hyn.tistory.com
이전 포스팅에서 사용한 UITapGestureRecognizer를 활용한 데이터 전달 문제를 리팩토링 하려고 한다
UUID 데이터 전달 문제 리팩토링
ContentView의 내부 프로퍼티 사용 시 문제점 (기존 방식)
- ContentView 내부 id 값과 UITapGestureRecognizer로 넘겨준 id 값이 같은 뷰를 찾기 위해 contentStackView.arrangedSubviews를 모두 순회해야 한다
- 뷰의 개수가 증가할수록 성능 저하가 발생할 수 있다
// contentStackView를 순회하면서 제스처 ID와 같으면 뷰 삭제
createMemberCardView.contentStackView.arrangedSubviews.forEach{ view in
if (view as? ContentView)?.id == id {
view.removeFromSuperview()
}
}
개선 방법: Dictionary 활용하는 방법
- [UUID : ContentView] 형태의 딕셔너리를 생성하여 관리
- ContentView 추가 시 UUID를 생성하여 딕셔너리에 저장
- 제스처를 통해 ID 전달은 동일
- 삭제 시 딕셔너리에 해당 UUID의 뷰를 찾아 제거
class CreateMemberCardViewController: UIViewController {
private let createMemberCardView = CreateMemberCardView()
private var contentViews: [UUID : ContentView] = [:]
...
// Add Content 버튼 액션
@objc private func touchUpInsideAddContentButton() {
// ContentView 생성
let contentView = ContentView()
let id = UUID() // 컨텐츠 ID 생성
contentViews[id] = contentView // 딕셔너리에 저장
// 삭제 제스처 추가
let removeButtonTapGesutre = CustomTapGesture(target: self, action: #selector(removeButtonTapGesture(_:)))
// 탭 제스처에 id 값 추가
removeButtonTapGesutre.id = id
// 삭제 버튼에 삭제 제스처 추가
contentView.titleView.removeButton.addGestureRecognizer(removeButtonTapGesutre)
// 생성한 View, StackView에 추가
createMemberCardView.contentStackView.addArrangedSubview(contentView)
// 딜리게이트 설정 (텍스트 뷰)
contentView.contentsView.textView.delegate = self
// 스크롤뷰 이동
createMemberCardView.scrollView.scroll(to: .bottom)
}
// ContentView 삭제 버튼 액션
@objc private func removeButtonTapGesture(_ gesture: CustomTapGesture) {
guard let id = gesture.id else { return } // 제스처에 저장된 ID 값 추출
// 제스처의 ID와 동일한 ContentView를 딕셔너리에서 찾아 삭제 (서버 저장 시 순서 보장 X)
if let removeView = contentViews[id] {
// 0.4초 동안 view의 투명도를 0으로 만들고, 이후 뷰 삭제
UIView.animate(withDuration: 0.4, animations: {
removeView.alpha = 0
}){ _ in
removeView.removeFromSuperview()
}
// 컨텐츠 뷰 딕셔너리에 값 제거
contentViews.removeValue(forKey: id)
}
}
기존 방식과 개선 방식 비교
비교 항목 기존 방식 (Subview 순회) 개선 방식 (Dictionary 활용)
삭제 방식 | arrangedSubviews를 순회하여 UUID 비교 후 제거 | UUID로 딕셔너리에서 직접 조회 후 제거 |
성능 | 뷰 개수가 많아질수록 성능 저하 | 딕셔너리 조회는 O(1)로 빠름 |
코드 가독성 | contentStackView 순회 코드가 필요함 | UUID 키 기반으로 관리하여 직관적 |
순서 유지 | arrangedSubviews의 순서를 그대로 유지할 수 있어 서버 저장 시 순서가 보장됨 | Dictionary는 순서를 보장하지 않으므로 서버 전송 시 순서가 유지되지 않음 |
결론
- 순서가 중요한 경우 → 기존 방식 유지 (arrangedSubviews 사용)
- 빠른 조회와 성능이 중요한 경우 → 딕셔너리 활용 ([UUID : ContentView])
'Today I Learn' 카테고리의 다른 글
Today I Learn: UIAlertController에 TextField 추가 및 데이터 사용 (0) | 2025.03.07 |
---|---|
Today I Learn: UILabel 내부 Padding 설정하기 (0) | 2025.03.06 |
Today I Learn(3): 동적으로 뷰 추가 및 삭제 (1) | 2025.03.05 |
Today I Learn(2) : MVVM 정리하기 (0) | 2025.03.04 |
Today I Learn(1) : 프로젝트 설계 (0) | 2025.03.03 |