[iOS / Swift] SnapKit 사용 기록

suyeon·2024년 1월 18일

iOS

목록 보기
1/7

새로운 프로젝트를 들어가게 되었는데, 개발 방식을 맞춰야해서 코드베이스 UI와 MVVM 패턴을 공부하게 되었다. 코드베이스를 아예 안해본건 아니지만 아예 모든 것을 코드로 만들어야 한다고 생각하니 벌써부터 땀이 눈을 가린다... 💦 아 눈물인가

그래도 실무에서는 Codebase + MVVM이 국룰이라 하니... 함 공부한 걸 기록해보려고 한다.

AutoLayout만 사용했을 때의 단점

일단 제일 큰 단점은 코드가 길어진다는 점이다. 그리고 매번 constraint를 주고자 하는 view의 translatesAutoresizingMaskIntoConstraints 값을 false로 바꿔야 한다는 번거로움이 있다.

현재 진행 중인 프로젝트를 하면서 몇 개의 뷰를 코드로 만든 적이 있는데, 확실히 코드가 길어지긴 했다.

SnapKit 설치

Cocoapods 설치

SnapKit 설치 전 의존성 매니저인 Cocoapods를 먼저 깔아야 한다.

$ sudo gem install cocoapods

Podfile 설정, SnapKit 설치

그런 다음, SnapKit를 설치하고자 하는 프로젝트 파일에서 터미널을 열고, 아래의 명령어를 입력한다.

$ pod init

그러면 프로젝트 디렉토리에 Pods라는 파일과 Podfile이라는 문서?가 생긴 것을 확인할 수 있다. 이제, SnapKit 깃허브 에 나와있는 것처럼 Podfile 안에 SnapKit와 그 버전을 명시해준다.

이때, pod 'SnapKit', '~> 5.7.0' 를 통해 5.7.0 버전을 다운받으려고 했으나 자꾸만

[!] CocoaPods could not find compatible versions for pod "SnapKit":
In Podfile:
SnapKit (~> 5.7.0)

라는 에러가 떴다.. SnapKit 공식 깃허브의 issue를 보니 똑같은 문제를 겪는 사람들이 몇몇 있었다. 달린 댓글들을 보니 아직 CocoaPods에 올라오지 않았다나.. 했다

그래서 5.6.0 버전으로 설치했다.

어쨌든 버전명까지 Podfile에 명시해줬다면 다시 터미널로 돌아가서

pod install

을 통해서 다운받아준다.

그리고 이런 식으로 라이브러리들을 추가한 이후에는 xcodeproj 파일이 아닌 xcworkspace 파일로 프로젝트를 열어야 한다.

SnapKit 사용기록

일단 처음이다보니 시작부터 클론 코딩을 하기엔 무리라고 생각해서 간단한 것부터 만들어보려고 했다. SnapKit+MVVM 을 공부하고 싶어서 찾아보던 와중, https://lsh424.tistory.com/68 요런 블로그 글을 발견하였다. (감사합니다 ㅎㅎ)
AutoLayout을 사용하셔서, 이 분의 view 만드는 코드를 내가 SnapKit를 사용한 코드로 바꿔보면서 간단히 연습하였다.

// layout
imageView.snp.makeConstraints { make in
	make.top.equalToSuperview().inset(10)
	make.centerX.equalToSuperview()
	make.width.equalToSuperview().multipliedBy(0.804)
	make.height.equalToSuperview().multipliedBy(0.804)
}
imageView.contentMode = .scaleAspectFit
        
nameLabel.snp.makeConstraints { make in
	make.top.equalTo(imageView.snp.bottom).inset(30)
	make.leading.equalTo(imageView.snp.leading).inset(10)
}
        
ageLabel.snp.makeConstraints { make in
	make.top.equalTo(nameLabel.snp.bottom).offset(20)
    make.leading.equalTo(nameLabel.snp.leading)
}
        
adoptionFeeLabel.snp.makeConstraints { make in
	make.top.equalTo(ageLabel.snp.bottom).offset(20)
	make.leading.equalTo(ageLabel.snp.leading)
	}
}
  • equalTo()에는 무조건 snp를 사용하여 해당 edge를 전달해야 한다.
  • multipliedBy는 스토리보드에서 multiplier와 같은 것이다.

inset과 offset

이건 사실 아직도 이해가 잘 가지 않는 부분이다. 위에서도 보면 inset 과 offset 을 둘 다 사용한 것을 볼 수 있다.

찾아보면 offset에 대해서는 "현재 뷰 constraint = 슈퍼뷰 constraint + offset 값" 라고 나온다. offset을 썼을 때 내가 상상한 대로 모양이 나왔다.

inset은 무조건 안쪽으로만 해당 값만큼의 spacing을 주는 것 같다.

위의 코드에서 ageLabel의 nameLabel에 대한 제약을 inset으로 20만큼 주게 되면 다음과 같이 원하지 않는 모양이 나온다. pomeranian이라는 nameLabel의 bottom에 대해서 inset, 즉 nameLabel의 '안쪽'으로 스페이싱이 들어가기 때문에 nameLabel.bottom - 20 (대충 쓰자면) 과 같은 값의 제약조건을 받게 되는 것이다.

원래 작성된 코드처럼 offset으로 20만큼 주게 된다면 다음과 같이 잘 나온다.

즉, inset(20)offset(-20)은 같은 셈이다.


inset과 offset이 은근 헷갈렸었는데 쓰다보니 이해가 가는 것 같다. 새로운 배우는 내용은 계속 추가해야겠다.

profile
낑낑슨....

0개의 댓글