이 포스트에서는 AutoLayout을 SnapKit 라이브러리를 사용하여 그립니다.
SnapKit(https://github.com/SnapKit/SnapKit)
아이폰 해상도
새로운 아이폰들이 매년 출시되면서 아이폰의 해상도가 점점 다양해지고 있습니다. (물론 안드로이드만큼 다양하진 않아서 너무 좋습니다,,) 아이폰에서 사용되는 해상도들을 보기 위해선 애플에서 제공하는 Display Reference 링크를 보면 됩니다.
Displays
Displays The display is a key part of the great user experience on iOS devices. Users interact with the display surface, and see the results after an app reacts to these touches and updates the displayed image. Apple continues to improve the display hardwa
developer.apple.com
애플에서 제공하는 디스플레이 레퍼런스지만 업데이트가 느린 것 같습니다. iPhoneX 이후에 XS, 11도 나왔는데 문서에는 아직 업데이트 되지 않았네요. 아래 링크는 아이폰 디자인을 코드화해주는 솔루션 업체인데, XS, 11의 해상도까지 함께 보여주고 있습니다.
The Ultimate Guide To iPhone Resolutions
The email address you entered is not valid. The trial is limited to 7 days. Only the days when you actually use the plugin are counted. Not downloading automatically? Click here to download.
www.paintcodeapp.com
아이폰에서 제공해주는 레퍼런스에는 Native Resolution (Pixels), UIKit Size (Points), Native Scale factor, UIKit Scale factor 총 4개의 컬럼으로 해상도를 알려주고 있습니다.
Native Resolution (Pixels)
실제 물리적인 해상도를 의미합니다. 우리가 통상적으로 모니터나 디프스플레이 스펙을 설명할 때 사용되는 가로, 세로 픽셀이 Native Resolution에 해당합니다.
UIKit Size (Points)
XCode에서 UIKit을 사용하여 코딩할 때 사용되는 뷰의 가로, 세로 사이즈 입니다. pt라는 단위로 사용됩니다.
iOS에서는 런타임에 UIKIt으로 코딩된 가로, 세로 길이에 UIKit Scale을 곱하여 실제 해상도로 표현해줍니다! iPhoneX의 폭을 예로들면 UIKit에서는 뷰의 폭 길이가 375pt지만 실제로 런타임에서 표시되는 화면의 폭은 375pt x 3 = 1124px이 됩니다. 하지만 UIKit Scale이외에 Native Scale컬럼도 존재하는데, 이 값과 UIKit Scale이 다른 경우에는 런타임에 UIKit Scale을 사용해 먼저 계산한 뒤 Native Scale 비율을 사용해 실제 해상도에 맞게 한번 더 계산하여 랜더링 해준다고 합니다.
그러므로 우리는 코딩할때 UIKit 컬럼에 나와있는 UIKit Size만 신경쓰면 됩니다!
AutoLayout에서 해상도 대응
디바이스 해상도에 따라 이미지가 비율에 맞게 보이게 하기 위해선 기준 해상도가 정해져있어야 합니다. UIKit Size기준으로 375 * 667 을 기준으로 할것인지, 큰 사이즈인 414 * 736을 기준으로 할것인지에 따라서 autoLayout 설정 값이 달라집니다. 이 포스트에서는 정확한 해상도 비율을 비교하기 위해서 가장 작은 사이즈인 iPhone SE (320 * 568)를 기준으로 하여 가장 큰 사이즈인 iPhone 11 Pro MAX(414 * 896) 와 비교하겠습니다.
먼저 iPhone SE에서 다음과 같은 화면을 그린다고 해봅시다.
총 3개의 정사각형 (빨강, 초록, 파랑)을 그려보았습니다. iPhone SE UIKit Size의 폭은 320 이므로 각각의 정사각형 한변의 길이는 100, 사각형 사이의 거리는 10으로 설정하여 총 320폭에 맞게 설정하였습니다. 뷰를 그리는 코드는 아래와 같습니다.
// ViewController.Swift
import UIKit
import SnapKit
class ViewController: UIViewController {
private let redView: UIView = {
let redView = UIView()
redView.backgroundColor = .red
return redView
}()
private let greenView: UIView = {
let greenView = UIView()
greenView.backgroundColor = .green
return greenView
}()
private let blueView: UIView = {
let blueView = UIView()
blueView.backgroundColor = .blue
return blueView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(redView)
view.addSubview(greenView)
view.addSubview(blueView)
redView.snp.makeConstraints { (make) in
make.width.height.equalTo(100)
make.left.equalToSuperview()
make.top.equalTo(view.safeAreaLayoutGuide)
}
greenView.snp.makeConstraints { (make) in
make.width.height.equalTo(100)
make.top.equalTo(view.safeAreaLayoutGuide)
make.left.equalTo(redView.snp.right).offset(10)
}
blueView.snp.makeConstraints { (make) in
make.width.height.equalTo(100)
make.top.equalTo(view.safeAreaLayoutGuide)
make.left.equalTo(greenView.snp.right).offset(10)
}
}
}
하지만 동일한 이 코드를 UIKit Size가 414 * 896인 iPhone 11 Pro Max에서 실행시키면 아래와 같이 보여지게됩니다.
iPhone SE에서 폭이 꽉찬 화면을 기대했지만 폭이 넓은 11 Pro Max에서는 오른쪽 공간이 남아버리는 현상이 나타납니다. iPhone SE에서 처럼 폭이 늘어난 만큼 정사각형 사이즈도 늘어나는 화면을 만들기 위해서는 정사각형 폭과 정사각형 사이 간격에 늘어난 비율만큼 곱해줘야합니다. 뷰 코드를 아래와 같이 고쳐보겠습니다.
// ViewController.Swift
import UIKit
import SnapKit
class ViewController: UIViewController {
private let redView: UIView = {
let redView = UIView()
redView.backgroundColor = .red
return redView
}()
private let greenView: UIView = {
let greenView = UIView()
greenView.backgroundColor = .green
return greenView
}()
private let blueView: UIView = {
let blueView = UIView()
blueView.backgroundColor = .blue
return blueView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(redView)
view.addSubview(greenView)
view.addSubview(blueView)
redView.snp.makeConstraints { (make) in
make.width.height.equalTo(100 * view.frame.width / 320)
make.left.equalToSuperview()
make.top.equalTo(view.safeAreaLayoutGuide)
}
greenView.snp.makeConstraints { (make) in
make.width.height.equalTo(100 * view.frame.width / 320)
make.top.equalTo(view.safeAreaLayoutGuide)
make.left.equalTo(redView.snp.right).offset(10 * view.frame.width / 320)
}
blueView.snp.makeConstraints { (make) in
make.width.height.equalTo(100 * view.frame.width / 320)
make.top.equalTo(view.safeAreaLayoutGuide)
make.left.equalTo(greenView.snp.right).offset(10 * view.frame.width / 320)
}
}
}
각각의 사각형 폭길이와 사각형 사이 간격에 view.frame.width / 320 을 곱해주었습니다.
view.frame.width의 값이 iPhone SE에서는 320이 나오고 iPhone 11 Pro Max에서는 414라는 값이 나오게 됩니다. 따라서 view.frame.width / 320을 계산하면 320 폭 화면에서 현재 화면 비율만큼 곱해주는 역할을 하게 됩니다. 따라서 코드를 저렇게 수정하고 11 Pro Max에서 실행시키게 되면 아래와 같이 보이게 됩니다.
이렇게 iPhone SE화면과 동일하게 비율에 맞게 커진 사각형을 볼 수 있습니다! 이렇게 여러 화면에서 폭 길이에 맞게 대응하기 위해서 autoLayout의 값에 비율을 곱해주는 방식으로 대응을 할 수 있습니다. 해당 포스트는 폭에 맞춰서 키웠고 동일하게 높이에 맞춰서 대응할 수도 있습니다.
'iOS' 카테고리의 다른 글
[iOS/Swift] 스토리보드 없이 UIScrollView 만들기 (using Snapkit) (2) | 2020.02.04 |
---|---|
[iOS13] 스토리보드 없이 프로젝트 시작하기 (0) | 2020.01.26 |
[RxSwift, RxCocoa] bind와 subscirbe의 차이점 (0) | 2020.01.07 |
[iOS/Swift] UIButton생성과 이벤트 핸들러 정의 (without stroyboard) (0) | 2019.07.16 |
[iOS] 커스텀 폰트 적용하기 (Swift) (0) | 2019.07.14 |