본문 바로가기

iOS/AutoLayout

iOS) Auto Layout 정복하기 (5/5) - 코드로 Auto Layout 설정하기

 

 

안녕하세요! 소들입니당 ☺️

드디어 AutoLayout 정복하기의 끝을 보려고 합니다!!!

저는 오늘부터 바른생활맨이 되기 때문에,,

운동도, 공부도 모두 다 죽었다 이말입니다 후후,,

 

쨌든

마지막 포스팅은 코드로 AutoLayout을 설정하는 방법에 대해 알아볼 거예요!

사실 Storyboard로 View를 그리는 것이 처음 iOS를 개발할 땐 매우 당연해보이고

아니 저렇게 좋은 스토리보드를 외않써? 할 수도 있지만,

협업을 해보시면요,, 스토리보드와 xib 무한 로딩에서 못나올 수도 있기에..^^

혹은 한문철도 못막는 무지성 충돌..^^

 

따라서 코드로 화면을 그리는 방법에 대해서도 꼭 숙지를 하고 계셔야 해요!

뭐 여러가지 방법이 있는데 저는 제일 많이 사용하는 방법에 대해 다뤄볼 거예요!

모든 포스팅은 편의 말투로 합니다~!!

 

 

 

 

1. 코드로만 View를 그려보자

 

 

1-1. Frame-Based Layout

 

 

override func viewDidLoad() {
    super.viewDidLoad()
    
    let sodeulButton: UIButton = .init(frame: .init(x: 100, y: 100, width: 200, height: 200))
    sodeulButton.backgroundColor = .yellow
    sodeulButton.setTitle("바른생활 소들맨"for: .normal)
    
    self.view.addSubview(sodeulButton)
}
 

 

 

꺄하하 소들님 이렇게 frame 설정해주면 버튼 잘 나오는데요?

하하하하

 

ㅇㅖ.. 물론 위처럼 해당 View의 frame을 직접 지정해주면,

(Button은 물론 View의 하위클래스입니당)

 

 

 

위처럼 내가 원하는대로 Button을 그릴 수 있긴 함!

AutoLayout 첫 포스팅때 뭐라했음 ㅎㅎ??

View의 위치나 크기를 설정할 때는 주어진 frame 그대로 그려버리는

Frame-Based Layout이 있다고 했잖음?

 

우리가 view를 만들 때 frame을 지정해주면 위처럼 

Frame-Based Layout로 그려버림

하지만 우린 뷰들간의 관계로 위치와 관계를 설정하는 AutoLayout을 설정하고 싶은 거잖음!?

 

 위에 예제는 치워버리고 AutoLayout으로 그리는 방법 보러가자~~

 

 

 

1-2. AutoLayout(오토 레이아웃)

 

AutoLayout을 설명할 때 뭐라 했냐면,

위치나 크기를 다른 객체를 이용해 "상대적"으로 제약을 주는 것이라 했음

 

따라서 우리가 만약 다음과 같은 제약조건을 가진 Button를 만들고 싶다면,

 

 

이를 코드로 짠다면 몇 가지 과정이 필요함 :)

 

 

 

1️⃣  addSubView로 뷰 추가해주기

 

 

override func viewDidLoad() {
    super.viewDidLoad()
    
    let sodeulButton: UIButton = .init(frame: .init())
    sodeulButton.backgroundColor = .yellow
    sodeulButton.setTitle("바른생활 소들맨"for: .normal)
    
    self.view.addSubview(sodeulButton)
}
 

 

 

코드로 AutoLayout을 설정하기 전에, 먼저 SuperView를 설정하는 addSubView작업이 선행되어 있어야 함

만약 addSubView 과정을 맨 마지막에 한다던가, Constraint 설정(3번 과정) 이후에 한다면

 

 

 

 

크래시나용~~~~!!!!!!!!!!!!!

 

 

 

2️⃣ translatesAutoResizeingMaskIntoConstraints를 false로 설정하기

 

 

override func viewDidLoad() {
    super.viewDidLoad()
    
    let sodeulButton: UIButton = .init(frame: .init())
    sodeulButton.backgroundColor = .yellow
    sodeulButton.setTitle("바른생활 소들맨"for: .normal)
    
    self.view.addSubview(sodeulButton)
   sodeulButton.translatesAutoresizingMaskIntoConstraints = false
}
 

 

 

translatesAutoResizeingMaskIntoConstraints 너가 뭔데 false로 설정해야 되나!!! 싶겠지만

일단 해주셈(뭔지에 대해선 다다다다~~음에 포스팅 할 거임)

 

기본 값이 true인데 일단은 대충

true -  AutoLayout을 따르지 않고 frame을 따르겠다(Frame-Based Layout)

false - AutoLayout을 따르겠다(AutoLayout)

이렇게 알면 됨

 

따라서

AutoLayout을 설정하고 싶다면 해당 뷰의 이 값을 false로 무조건 설정 해주어야 함

 

 

 

3️⃣ 제약조건(Constraints) 설정하기

 

 

override func viewDidLoad() {
    super.viewDidLoad()
    
    let sodeulButton: UIButton = .init(frame: .init())
    sodeulButton.backgroundColor = .yellow
    sodeulButton.setTitle("바른생활 소들맨"for: .normal)
    
    self.view.addSubview(sodeulButton)
   sodeulButton.translatesAutoresizingMaskIntoConstraints = false

    sodeulButton.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 100).isActive = true
    sodeulButton.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 100).isActive = true
    sodeulButton.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -80).isActive = true
}
 

 

 

위처럼 설정하면 되는데!!!!!

위의 코드가 이해가 안갈까봐 trailing constraint로 대충 설명 갖고옴

 

 

 

 

먼저 AutoLayout을 설정하고 싶은 View

topAnchor / leadingAnchor / trailingAnchor / bottomAnchor 등등..

에 대고 constraint라는 메서드를 호출해주면 되는 것임

뒤에 Anchor가 붙긴 했지만, Anchor를 빼고 생각해도 무방함!!!

 

이때, 제일 중요한 건 마지막 isActive 상태를 true로 바꿔주어야 함

코드로 설정할 경우 해당 constraint는 기본이 비활성화기 때문에, 활성화를 시켜줘야 함

 

이렇게 해줄 경우, 나는 아무런 frame을 설정하지 않았지만,

코드로 설정해준 AutoLayout에 의해

 

 

 

 

이렇게 잘 나옴!! :>

근데 의문. 나는 trailing을 80만큼 띄우고 싶은데, 왜 constant 설정을 -80으로 해줘야 함!?!?

에 대한 의문 풀어dream

 

 

 

 

2. 코드로 AutoLayout 설정할 때 알아두면 좋은 내용 모음

 

 "모음" 집으로 내가 헷갈렸거나 누군가 헷갈려서 질문을 한다면

계속 추가될 수 있음

 

 

 

2-1. trailingAnchor, bottomAnchor constant 설정 시 주의점

 

 

지금껏 스토리보드로 AutoLayout을 설정할 때 분명

 

 

 

 

이렇게 trailing, bottom에 각각 80을 주면

trailing에서 80떨어진 만큼, bottom에서 80 떨어진 만큼 위처럼 당연히 그려졌잖음?

(참고로 bottom은 SafeArea에 걸림!)

 

근데 이게, 코드에서도 마찬가지로 80씩 줘버리면 어케 되냐면

 

 

sodeulButton.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 80).isActive = true
sodeulButton.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 80).isActive = true
 

 

 

 

 

이렇게 ㅔ 멀리 멀리 사라진답니다...ㅎ

그 버튼.. 좋은 버튼이었어..

 

따라서 코드로 constant를 설정할 때, trailingAnchor / bottomAnchor에 한해서

storyboard와 달리 -(minus)를 붙여주어야 한다는 사실 잊지 마셈

(일단 생각나는 건 이 둘인데 더 있으면 추가하겠음)

 

당연히 -80으로 설정하면

 

sodeulButton.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -80).isActive = true
sodeulButton.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -80).isActive = true
 

 

 

 

 

원하는 모양으로 잘 나옴!!!

 

 

 

2-2. self.view(rootView)에 붙일 경우, SafeAreaLayoutGuide를 사용하자

 

 

사실 위 예제처럼 constraint의 기준이 되는 view를  self.view로 잡아도 되지만

 

 

 

 

혹여나 이 난리를 피하고 싶다면,

다음고 ㅏ같이 SafeAreaLayoutGuide에 잡는 게 바람직함

 

 

sodeulButton.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 20).isActive = true
sodeulButton.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor, constant: 20).isActive = true
 

 

 

그러면 다음과 같이 잘 나옴

 

 

 

 

safeArea를 사용하지 않는 화면의 경우 상관 없겠지만,

보통 애플이 safeArea 사용을 권장하기 때문에!!!!

self.view에 붙일 경우, self.view가 아니라 self.view.safeLayoutGuide 를 사용합시다!!

 

 

 

2-3. .isActive = true 를 매번 하기 귀찮다면 이렇게도 쓸 수 있다

 

 

NSLayoutConstraint.activate([
    sodeulButton.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 20),
    sodeulButton.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor, constant: 20)
])
 

 

 

이렇게 NSLayoutConstraint.activate를 이용해서

위처럼 activate 메서드 안에 []로 Constraints를 나열해주면,

각각 isActive = true를 해줄 필요 없이 전체 활성화로 설정이 가능함!!!!

 

 

 

2-4. widthAnchor, heightAnchor 같이 기준 뷰 없이 constant만 설정하고 싶은데요

 

cosntraint를 설정하는 함수는 매우 다양하고 많지만

이처럼 기준 뷰가 없을 경우 constraint(equalTo: constant:) 메서드를 쓰는게 아니라

 

 

sodeulButton.widthAnchor.constraint(equalToConstant200).isActive = true
sodeulButton.heightAnchor.constraint(equalToConstant200).isActive = true
 

 

 

 constraint(equalToConstant:) 를 사용하면 됨니당

 

 

 

 

 

 

 

.

.

.

드디어 AutoLayout에 대한 포스팅이 끝났네요 :)

어우 끝맺고 나니까 속시원한데 Snapkit같은 거 사용법도 나중에 포스팅 할게요 ~.~

도움을 받고 가는 사람이 많길 바라며!!!

오타나 잘못된 내용 피드백은 환영입니다!!!

 

 

 

 



Calendar
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
최근 댓글
Visits
Today
Yesterday