[UIKit] SnapKit: Card Layout

Junyoung Park·2022년 12월 25일
0

UIKit

목록 보기
130/142
post-thumbnail
post-custom-banner

Snapkit PART 2 - How to use Snapkit in iOS - SnapKit Tutorial for Autolayout Constraints

SnapKit: Card Layout

구현 목표

  • 스냅킷을 통한 레이아웃 연습

구현 태스크

  • 복잡한 레이아웃 뷰 구성

핵심 코드

private func applyConstraints() {
        firstImageView.snp.makeConstraints { make in
            make.leading.top.bottom.equalToSuperview()
            make.width.equalToSuperview().offset((-(frame.width/2) - 20))
        }
        secondImageView.snp.makeConstraints { make in
            make.top.trailing.equalToSuperview()
            make.leading.equalTo(firstImageView.snp.trailing).offset(1)
            make.height.equalToSuperview().offset((-(frame.width/2) - 1))
        }
        thirdImageView.snp.makeConstraints { make in
            make.leading.equalTo(firstImageView.snp.trailing).offset(1)
            make.top.equalTo(secondImageView.snp.bottom).offset(1)
            make.trailing.bottom.equalToSuperview()
        }
    }
  • frame 사이즈를 토대로 레이아웃의 오프셋을 계산할 것이기 때문에 init 단계가 아니라 layoutSubviews라는 실제 프레임 사이즈가 주어진 시점에서 해당 함수를 실행해야 함
func configure(with models: [PhotoModel]) {
        zip(imageViews, models).forEach { imageView, model in
            if let image = CacheManager.shared.get(model: model) {
                imageView.image = image
            } else {
                downloadImage(model: model, imageView: imageView)
            }
        }
    }
    
    private func downloadImage(model: PhotoModel, imageView: UIImageView) {
        guard let url = URL(string: model.urls.full) else { return }
        var imageSubscription: AnyCancellable?
        imageSubscription = NetworkService.download(with: url)
            .receive(on: DispatchQueue.main)
            .sink(receiveCompletion: NetworkService.handleCompletion(completion:), receiveValue: { data in
                guard let image = UIImage(data: data) else { return }
                CacheManager.shared.save(model: model, image: image)
                imageView.image = image
                imageSubscription?.cancel()
            })
    }
  • 데이터 모델 세 개로 이루어진 배열을 인자로 받아 뷰 내의 서브 뷰 세 개(이미지 뷰)에 다운로드받은 이미지를 넣어야 하기 때문에 zip을 통해 각 매칭을 시킴

구현 화면

스냅킷을 사용하는 것은 좋지만, 이렇게 할 거라면 컴포지셔널 레이아웃이 가장 적합할 것 같은데... 일단 강의대로 해보자.

profile
JUST DO IT
post-custom-banner

0개의 댓글