[Swift] set size and position for view(CGRect, AutoLayout)
프로젝트를 하다보니 버튼, 이미지뷰 등을 CGRect로 배치를 하였으나 하나 하나 설정을 해줘야 되는 번거로움과 업데이트가 너무 힘들어서 다른 방법을 찾다보니 AutoLayout을 알게 되었고 코드를 수정을 하려고 한다.
CGRect (참고)
: A structure that contains the location and dimensions of a rectangle.
CGRect(x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat)
var imageButton: UIButton = {
var button = UIButton(type: .custom)
button.tintColor = .black
button.frame = CGRect(x: 90, y: 110, width: 70, height: 70)
return button
}()
x, y를 통해서 위치를 정하고 width, height를 통해서 크기를 정합니다.
장점
- 세밀하게 위치를 조정할 수 있습니다
단점
- 모든 프레임에 각각 입력을 해야합니다
- 변경사항이 있을 때 업데이트가 어렵습니다
위와 같이 코드로 사용을 하였으나 단점을 직접 느끼다, 새로운 방법을 찾게 되었고 아래와 같은 AutoLayout을 찾아보았습니다.
AutoLayout (참고)
: Auto Layout은 뷰 계층 구조에 있는 모든 뷰의 크기와 위치를 해당 뷰에 적용된 제약 조건을 기반으로 동적으로 계산합니다. 제약 기반 접근 방식을 통해 내부 및 외부 변경 모두에 동적으로 응답하는 사용자 인터페이스를 구축할 수 있습니다.
override func viewDidLoad() {
super.viewDidLoad()
let redView = UIView()
redView.backgroundColor = .systemRed
redView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(redView)
redView.widthAnchor.constraint(equalToConstant: 100).isActive = true
redView.heightAnchor.constraint(equalToConstant: 100).isActive = true
redView.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true
redView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
}
위 코드를 아래와 같이 바꿀 수도 있습니다.
override func viewDidLoad() {
super.viewDidLoad()
let redView = UIView()
redView.backgroundColor = .systemRed
redView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(redView)
NSLayoutConstraint.activate([
redView.widthAnchor.constraint(equalToConstant: 100),
redView.topAnchor.constraint(equalTo: view.topAnchor, constant: 100),
redView.heightAnchor.constraint(equalTo: redView.widthAnchor, multiplier: 1),
redView.centerXAnchor.constraint(equalTo: view.centerXAnchor)
])
}
Safe Area
콘텐츠가 상태바, 네비게이션바, 툴바 등을 가리는 것을 방지하는 영역입니다.
Constraint
뷰 스스로 또는 다른 뷰의 관계를 속성을 통하여 정의합니다.
제약 우선도 (Constraint Priorities)
오토레이아웃은 제약 우선적으로 레이아웃에 적용되며 같은 속성의 다른 제약과 경합이 된다면 낮은 제약은 무시됩니다.
- 콘텐츠 허깅 우선도(Content hugging priority) : 콘텐츠 고유 사이즈보다 뷰가 커지지 않도록 제한합니다. 다른 제약사항보다 우선도가 높으면 뷰가 콘텐츠 사이즈보다 커지지 않습니다.
- 콘텐츠 축소 방지 우선도(Content compression resistance priority) : 콘텐츠 고유 사이즈보다 뷰가 작아지지 않도록 제한합니다. 다른 제약사항보다 우선도가 높으면 뷰가 콘텐츠 사이즈보다 작아지지 않습니다.
앵커 (Anchor) - 참고
오토레이아웃을 코딩으로 구현하여 제약을 만들기 위해서 사용합니다.
Layout Anchor는 위에 언급되었던 것과 같이 실행을 하면 됩니다.
var leftAnchor: NSLayoutXAxisAnchor { get }
: view 프레임의 왼쪽 가장자리로 제약 조건을 만듭니다.
var topAnchor: NSLayoutYAxisAnchor { get }
: view 프레임의 위쪽 가장자리로 제약 조건을 만듭니다.
var rightAnchor: NSLayoutXAxisAnchor { get }
: view 프레임의 오른쪽 가장자리로 제약 조건을 만듭니다.
var bottomAnchor: NSLayoutYAxisAnchor { get }
: view 프레임의 아래쪽 가장자리로 제약 조건을 만듭니다.
var centerXAnchor: NSLayoutXAxisAnchor { get }
: view 프레임의 가로 중심으로 제약 조건을 만듭니다.
var centerYAnchor: NSLayoutYAxisAnchor { get }
: view 프레임의 수직 중심으로 제약 조건을 만듭니다.
var heightAnchor: NSLayoutDimension { get }
: view 프레임의 높이를 나타내는 Layout Anchor입니다.
var widthAnchor: NSLayoutDimension { get }
: view 프레임의 너비를 나타내는 Layout Anchor입니다.
var leadingAnchor: NSLayoutXAxisAnchor { get }
: view 프레임의 앞 가장자리를 나타내는 Layout Anchor입니다.
var trailingAnchor: NSLayoutXAxisAnchor { get }
: view 프레임의 후행 가장자리를 나타내는 Layout Anchor입니다.
leading 과 left 그리고 trailing 과 right 의 차이는 글을 읽는 순서가 왼쪽이라서 다른 점이 없어보이겠지만
leading 은 텍스트의 시작점이며, trailing 은 텍스트의 끝점입니다.
나라별로 읽는 순서가 다르기에 LTR(Left To Right) 과 RTL(Right To Left) 원활히 지원을 하기 위해서
left, right 보다는 leading, trailing을 사용하는 것을 권장합니다.
var firstBaselineAnchor: NSLayoutYAxisAnchor { get }
: view 에서 텍스트의 맨 위 줄에 대한 기준선을 나타내는 Layout Anchor입니다.
var lastBaselineAnchor: NSLayoutYAxisAnchor { get }
: view 에서 텍스트의 맨 아래 줄에 대한 기준선을 나타내는 Layout Anchor입니다.
newLabel = UILabel()
newLabel.text = "new"
newLabel.leadingAnchor.constraint(equalTo: baseLabel.trailingAnchor,constant: 8).isActive = true
newLabel.topAnchor.constraint(equalTo: baseLabel.firstBaselineAnchor).isActive = true