기어가더라도 제대로

야곰 오토레이아웃 필기(Intrinsic size, UIScroll View 등) 본문

UIKit 기초

야곰 오토레이아웃 필기(Intrinsic size, UIScroll View 등)

Damagucci-juice 2022. 5. 4. 16:59

AutoLayout

제약을 표현할 때는 관계를 표현한다.

양쪽의 수식이 동등하지 않을 수 있다. ex ) 크거나 같다. 작거나 같다. 최대 최소한의 크기를 정할 때 사용할 수 있다.
뷰들관의 간격이나 컨스트레인트를 합해서 사용하는 부분이다. 값을 고정하는 것보다 복잡한 상황일 수 있다.

Priorities

컨스트레인트 간에 우선도

Intrinsic Content Size(고유 컨텐츠 사이즈)

기본사이즈 O 기본사이즈 X
레이블, 버튼, 스위치, 텍스트 필드 뷰, 텍스트 뷰, 이미지 뷰(이미지 로딩되면 O)
슬라이더(높이 O)

정의

뷰의 현재 사이즈를 기반으로 사이즈를 계산한다.
텍스트뷰는 스크롤이 가능하냐 안가능하냐를 기준으로 스크롤 O -> 사이즈 없고, 스크롤 X -> 사이즈가 있다.

사용

Text Label 같은 경우 위치(leading, top)만 정해줘도 가서 붙음, 왜냐면 이미 사이즈를 본인이 가지고 있기 때문이다. 버튼도 마찬가지다.

슬라이더는 높이는 정해져 있어서 top 덕분에 안정이 되지만, leading 만 붙이면 부족해서 너비 값도 넣어줘야한다.

예외 사용

Place holder 사이즈를 줘서 Intrinsic Size를 줄 수 있다. 단 이것은 실행중엔 안되고 스토리보드상에서만 보이는 효과다.

실제 사이즈를 주려면, UIView 클래스를 만들어서

override var intrinsicContentSize: CGSize {

return CGSize(width: 50, height: 50)

}

를 만들어주면 바로 딱 붙는다.

이런식으로 고유 사이즈가 없는 뷰라고 하더라고 커스텀 클래스 지정을 통해 고유 사이즈를 지정해 줄 수 있다.


Content compression resistance <-> content hugging?

  • Content compression resistance
    • 외부에서 압력을 줄 때 버티는 힘
  • Content hugging
    • 늘어나지 않으려고 버티는 힘

이 두 가지의 기준은 Intrinsic Content Size 이다.

줄여서 CRCH 라고 부른다. Priority를 기준으로 움직인다.

누가 줄어들고 누가 늘어날지 결정해주는 힘

기준) 이 뷰가 화면에 꼭 있어야하는지? 늘어나면 보기 싫은지 아닌지를 결정하는게 CRCH이다. 실습을 통해서 확인하자.

실전 연습

Add Missing Constraints 랑 Reset to Suggested Constraints 는 절대 절대 절대 사용하지 않는 것을 추천한다.
Clear Constraints 이것만 써야 한다.

컨스트레인트를 벗어나면 노란색선이 뜨는데, Update Frame을 사용하면 제약걸린대로 다시 가서 자리를 잡는다.

Embed in View

Stack View, view, scroll view 에 선택된 객체들을 바로 넣어주는 기능

Constraints 거는 방식

초보일 때는 밑에 있는 툴을 쓰고, 익숙해지면 control 누르고 당겨서 쓰자.

가로 세로 비율, Aspecto ratio

Option 키를 잘 활용하면 편하게 비율 설정이 가능하다.

내부에서 드래그를 당기면 자기의 가로세로 비율, 다른 객체로 당기면 다른 객체와의 가로 세로 비율을 조정 가능하다.

Simple Constraints

Auto Layout CookBook을 한번 해보죠~

두배 제약을 주려면 ?? Multiflier 를 고민해보자

Stack View

Axis(축)
Distribution(배분) (중요)
Alignment(정렬) (중요)
Spacing(간격)

Wwdc15 218 session 들어보기 !

링크되어 있는 자료 보기 전에 ! ㅎㅎ

Distribution

.fill : hugging priority 가 적은 친구(?)들이 늘어납니다.
.fillEqually: 동일한 길이로 늘어납니다.
.fillProprotionally: 비율 대로 늘어납니다.
.equalSpacing : 같은 간격으로 늘어납니다.
.equalCentering : 뷰에 중앙선이 있는 것처럼 정렬이 됩니다.

Alignment

.fill : axis 의 반대 방향으로 어떻게 정렬 결정
.leading : 왼쪽 선에 맞춘다. 고유 사이즈 만큼 보인다.
.top : 가로 스택인 경우에 탑에 맞춘다.
.firstBaseline : 뷰의 첫줄(제목)을 맞춰줍니다.
.center : 센터 선에 뷰들을 맞춰 줍니다.
.trailing : 오른쪽에 선에 맞춰줍니다.
.bottom : 뷰의 밑바닥에 맞춰줍니다.
.lastBaseline : 글자의 마지막 선에 맞춰줍니다.

간단한 스택뷰(예제)

레이블 - 이미지 뷰 - 버튼

Debugging Auto Layout

불완전한 레이아웃
불분명한 레이아웃
논리 오류

충족하지 못한 레이아웃

언제 일어나는가?

애매한 레이아웃

lldb 를 알면 더 잘 실행할 수 있다.


코드로 제약 걸기

Layout Anchors

폭풍 처럼 지나갔다.

0.

Let button = UIButton()

1.

button.translatesAutoresizingMaskIntoConstraints = false

2.

Button.leadingAnchor.constraint(~.leading, constant: 20).isActive = true (사방 걸어주기)

~.isActive = true 이것은 constraint 라는 메서드가 Constraint 자체를 반환하는데, 따로 저장하지 말고 선언하는 동시에 활성화 하라는 뜻이다.

그리고 상수가 어떤 때는 음수더라도 어떤 때는 양수이니 잘 생각해야하고,

대소 관계 EqualTo 인지, Greater than or Equal 인지 Less Than or Equal 인지 잘 생각해야한다.

이에 따라 Constant 의 양수, 음수가 결정되기도 하고, 하여튼 제일 골치가 아픈 부분이다.

Safelayout 을 상수로 지정하는 방법

let safeArea = view.safeAreaLayoutGuide

아무튼 이 방법을 가장 추천하는데, 오류를 컴파일 타임에 검출해준다. 예를 들어, leading 을 bottom 이랑 비교한다던지 하는 경우, 오류를 반환하는데, NSLayoutConstraint 는 오류를 반환하지 않는다. 이는 Anchor 는 매개변수로 제네릭을 사용하는데 NSLayoutConstraint 는 그렇지 않아서 라고 한다.

NSLayoutConstraint

사방 Constraint 를 생성해주고, 이들을 배열의 요소로 한꺼번에 넘겨서 isActive 를 해주면 되겠다.
UI 객체를 다수 코드로 생성하면, Constraints 를 각각 걸어줘야하는데, NSLayoutConstraint 를 사용하면 한 곳에서 여러 객체들의 제약사항을 관리할 수 있어 편리하다.

    NSConstraint.active([
    // 각종 제약사항 나열,
    ])

Safe Area, Layout Margin

  • Safe Area
    • 컨텐츠를 기기 마다 화면에 표시할 수 있는 안전지대를 말한다. 어떤 기종은 Round 처리되어 있어 Safe Area가 작기도 하다.
  • Layout Margin
    • View 와 Content 사이의 공간
    • Default 설정이 되어있어서 값을 확인하고 싶으면, Inspector, Layout Margin 으로 확인한다.
    • Checkbox 를 체크 안하면, View에 붙는데, 체크를 하게 되면, View의 Content Margin 에 붙는다.

UIScrollView 설정 순서

  1. UIScrollView를 추가
    1. 뷰와 Constraint 를 설정
    2. Content Layout Margin 을 해제
  2. UIScrollView 위에 뷰를 하나 얹고 이를 Content View 라 이름 짓기
  3. Content View의 Constraints를 설정
  4. (옵션) 상하 스크롤을 하고 싶다면, ScrollView와 Content View의 너비를 동일하게 설정
  5. (옵션) 좌우 스크롤을 하고 싶다면, ScrollView와 Content View의 높이를 동일하게 설정
  6. 넣고자 하는 아이템을 넣고 Constraints 를 설정

왜 이런 과정을 겪느냐하면, UIScrollView와 View 모두 Intrinsic Size가 잡혀있지 않기 때문에 이런 과정을 거칩니다.
결론적으로 6번의 작업에서 Item 이 갖는 크기로 인해 Content View 와 UIScroll View의 크기가 정해집니다.

Content Layout Guide VS. Frame Layout Guide

Content Layout Guide Frame Layout Guide
스크롤 뷰에 들어가는 컨텐츠와 스크롤뷰의 관계를 정의 스크롤 뷰와 화면에 보여지는 프레임의 관계를 정의

만약 스크롤이 되는 중에도 화면의 일부분에 항상 특정한 Label 이 보이게 하고 싶다면?
-> 해당 Label 의 Constraints를 Frame Layout Guide 와 맺어야 한다.

Dynamic Type

글자의 크기를 동적으로 변하게 한다.
Label 의 글자 크기를 상수 값으로 적용하면 접근성 측면에서 사용자가 배율을 높이거나 해도 글자가 그대로인데, Dynamic Type 을 적용하면 확대를 하면 확대 되고 축소를 하면 축소되는 형태를 띈다.

Table View Controller 에 관한 약간의 꿀팁..?

테이블 뷰의 Cell 은 기본적으로 UIImageView 를 속성으로 가지고 있습니다. 여기에 준비한 이미지를 담는 다면 어떤 일이 발생할까요? 이미지마다 크기가 다르니 이미지의 크기마다 Cell 의 imageView가 넘쳐나거나 줄어들거나 할 것입니다. 여기서 고려할 옵션은 두가지입니다.

  1. ClipToBound
  2. myImageView를 탑재한 Custom Cell

구현은 직접하고 이만 글을 마치겠습니다.

Comments