장바구니 화면 전체 구현
상품 수량 조절 컴포넌트(QuantityControl) 만들고 셀에 적용
상품 정보 + 이미지 + 총액 계산 UI 구성
NotificationCenter로 실시간 장바구니 상태 업데이트
비동기 이미지 로딩 + NSCache로 이미지 캐싱
수량 조절 기능은 QuantityControl이라는 커스텀 UIView로 구현함
+와 – 버튼을 포함하고 있고 수량이 변경될 때 외부로 콜백을 전달하도록 설계함
사용자가 수량을 0으로 줄이려 할 경우에 곧바로 삭제되지 않고 UIAlertController를 통해서 삭제 여부를 확인하도록 처리
만약 사용자가 취소를 선택하면 수량을 다시 1로 복원하는 방식
총 수량, 총 가격은 CartManager 싱글톤 객체에서 계산
값을 뷰컨트롤러에서 가져와 UI에 실시간으로 반영해서 장바구니 전체 상태를 직관적으로 확인할 수 있도록 함
장바구니의 상태는 NotificationCenter를 통해 다른 화면에도 반영
상품 수량이 변경되거나 삭제되면 해당 변경 사항은 전역적으로 브로드캐스팅돼서 CartViewController에서 테이블뷰를 리로드하고 총액 업데이트
상품 이미지는 비동기 방식으로 로드, async/await 패턴 적용
NSCache를 활용해서 이미 한 번 불러온 이미지는 메모리 내에서 재사용할 수 있도록 해서 네트워크 자원을 절약하고 로딩 속도 개선 에러가 발생한 경우엔 기본 이미지 아이콘으로 대체
문제 - 수량을 0으로 만든 후 취소하면 셀에 아무것도 안 뜸
원인 - quantity = 0으로 이미 화면이 바뀐 뒤라서 UI 복구 안 됨
해결 - 취소 누르면 수량을 강제로 다시 1로 복원해주는 코드 추가
alert.addAction(UIAlertAction(title: "취소", style: .cancel, handler: { _ in
cell.quantityControl.quantity = 1
}))
문제 - 이미지 로딩이 느릴 때 로딩 중 표시가 없어 UX 나쁨
해결 - UIActivityIndicatorView + 비동기 작업 취소 처리로 개선
indicatorView.startAnimating()
imageLoadTask = Task {
let image = try await fetchImageAsync(...)
productImageView.image = image
indicatorView.stopAnimating()
}
해결 - UITableView.backgroundView에 텅 라벨을 보여줌
if cartManager.items.isEmpty {
cartView.tableView.backgroundView = emptyLabel
}
NSCache로 이미지 캐싱하면 중복 로딩 방지 가능
NotificationCenter로 ViewModel 없이도 전역 상태 업데이트 가능
커스텀 뷰를 만들 땐 콜백 클로저로 로직 분리하는 게 깔끔함
Alert 취소 동작도 로직을 넣어야 안전함