[Auto Layout] Constraint Priorities, Intrinsic Content Size, CRCH

Lily·2021년 11월 30일
0

📐 Auto Layout

목록 보기
2/4

안녕하세요! 릴리입니다🙂

오늘은 Auto Layout의 Constraint Priorities의 개념과 Intrinsic Content Size에 대해 알아보고, Constraint Priorities가 Intrinsic Content Size에 어떻게 적용될 수 있는지에 대해서도 알아보도록 하겠습니다.🧐

이 글은 Apple Document야곰닷넷의 Auto Layout 정복하기를 참고하여 작성되었습니다.
 Anatomy of a Constraint
🐻 야곰 닷넷 _ Auto Layout 정복하기


Constraint Priorities


Constraint Priorities를 알아보기에 앞서
Constraint를 등식이 아닌 부등호로도 표현할 수 있는데요,
먼저 Constraint Inequalities를 간단하게 짚어보고 가도록하겠습니다.

Constraint Inequalities

등호가 아닌 >= > <= <의 부등호로도 constraint를 설정할 수 있습니다.

Constraint Inequalitiy로 view의 size의 최소값 또는 최대값을 지정해 줄 수 있겠죠!

// Setting the minimum width
View.width >= 0.0 * NotAnAttribute + 40.0
 
// Setting the maximum width
View.width <= 0.0 * NotAnAttribute + 280.0

하지만 넓이의 최소값, 최대값만으로는 view가 어디에 위치해야할 지와 높이와 같은 정보를 충분히 제공해주지 못합니다.
따라서 항상 다른 constraints(equality)를 충족시키며, 최소값과 최대값사이의 넓이로 지정해주게 됩니다.

하나의 constraint equality를 두개의 Constraint Inequalitiy식으로 표현도 가능합니다. 단, 부등호의 기준이 되는 지점은 같아야합니다.

// A single equal relationship
Blue.leading = 1.0 * Red.trailing + 8.0
 
// Can be replaced with two inequality relationships
Blue.leading >= 1.0 * Red.trailing + 8.0
Blue.leading <= 1.0 * Red.trailing + 8.0

그렇다면 하나의 Constraint Inequalitiy만으로 size와 location을 계산할 수 있을까요?
정답은 안됩니다.


Constraint Priorities

constraint는 Priorities(우선도)가 있습니다.

priority는 1~1000사이에서 설정할 수 있고, prority의 숫자가 클수록 우선도가 높은 것인데요!

충돌되는 constraint가 있다면 높은 priority를 기준으로 size와 location이 결정됩니다. 그리고 낮은 constraint는 무시되기도 합니다.(만약 constraint끼리 상반된다면요)

그렇다고 해서 priority가 다른 다수의 constraint가 복수 적용될 수 없는 것은 아닙니다. 아래와 같이 충돌될 경우가 없다면, 두 개의 constraint를 동시에 적용시킬 수 있습니다.

View.Leading <= 1.0 * View.Trailing + 100.0  // priority : 1000
View.Leading = 1.0 * View.Trailing + 20.0  // priority : 500

Intrinsic Content Size


지금까지는 constraint로 view의 size와 position을 결정하는 방법들을 살펴보았습니다.

그런데 몇몇의 view는 주어진 현재의 content에 따라 size가 결정되기도 합니다. 예를 들면 button의 사이즈는 "타이틀의 길이 + 마진"에 따라 constraint없이도 컴퓨터가 계산을 할 수 있습니다. 이렇게 current content에 기반하여 결정되는 size를 Intrinsic Content Size라고 합니다.

모든 view가 Intrinsic Content Size가 적용되는 것은 아닙니다. 만약 적용되는 view라면 Intrinsic Content Size에 따라 넓이와 높이를 정의할 수 있습니다. 이러한 view는 contetnt에 따라 size가 결정되기 때문에 별도로 넓이와 높이에 관련된 constraint를 주지 않아도 빨간 선이 생기지 않습니다!

Intrinsic Content Size가 적용되는 view를 알아볼까요?

  • UIView and NSView : Intrinsic Content Size가 없습니다.(대신, custom class로 Intrinsic Content Size를 코드로 설정할 수 있습니다)

  • Sliders : Intrinsic Content Size는 width만 정합니다. (위 표는 오타인 것 같습니다.)

  • Labels, buttons, switches, and text fields : text의 양과 사용된 font로 height와 width 모두 정합니다.

  • image view : 빈 image view는 Intrinsic Content Size가 없습니다. 단, image를 추가하는 순간 image의 size = Intrinsic Content Size로 정해집니다.

  • text view
    text view는 좀 더 복잡합니다. content에 따라, scroll이 가능한지 여부에 따라, 다른 constraint가 view에 적용되었는지에 따라 Intrinsic Content Size가 달라질 수 있습니다.

    • scroll 가능 : Intrinsic Content Size 없음, 따라서 width, height 지정해주어야 함(안하면 width: 0, height: 0로 안 보임)
    • scroll 불가능 : 디폴트로 Intrinsic Content Size는 줄바꿈이 없는 text의 size에 기반해서 계산됩니다.

CRCH

Intrinsic Content Size로 view의 width와 height를 정한다면, width와 height 관련 constraint을 정해주지 않아도 됩니다. 대신 Content Compression Resistance와 Content Hugging의 priority를 관리해주어야합니다. 다른 constraints에 의해 영향을 받기 때문인데요.

constraint가 Intrinsic Content size를 변화시키려고 할 때, 늘어나게 둘 것인지, 아니면 줄어들게 둘 것인지를 정하는 힘이 바로 Content Compression Resistance와 Content Hugging입니다.

그렇다면 Content Compression Resistance와 Content Hugging이 무슨 개념인지 알아보도록 하겠습니다.🤓

Content Compression Resistance (CR)

외부에서 view를 찌그러뜨리려고 할 때, intrinsic content size를 유지하기 위해 버티는 힘.
수평 또는 수직으로 적용됩니다.

// Compression Resistance
View.height >= 0.0 * NotAnAttribute + IntrinsicHeight
View.width >= 0.0 * NotAnAttribute + IntrinsicWidth
 
// Content Hugging
View.height <= 0.0 * NotAnAttribute + IntrinsicHeight
View.width <= 0.0 * NotAnAttribute + IntrinsicWidth

Content Hugging (CH)

view가 intrinsic content size에 딱 맞게 줄어드려고 하는 힘. 그 이상으로 늘어나지 않으려고 하는 힘.
수평 또는 수직으로 적용됩니다.

CR(Compression Resistance)과 CH(Content Hugging)은 각각 Horizontal, Vertical Priority를 가질 수 있습니다.

디폴트로 view는 CH는 250 priority를, CR는 750 priority를 가지고 있습니다. 따라서 CH가 힘이 더 약하기 때문에 view는 줄어들기보다 늘어나가기가 쉽습니다.

CR과 CH는 반대 방향의 힘이기 때문에 priority를 가지고 어떤 힘을 적용시킬지를 정해주어야합니다.
🌟 어떤 view가 content에 맞게 모두 보여져야하는지, 공간이 넉넉치 않을 때 어떤 view가 줄어들어도 되는지, content이상으로 늘어나게 하면 미관상 보기 안좋은지 등 기준을 고려할 때 활용할 수 있습니다!


UIView의 Intrinsic Content Size 설정하기

Placeholder

UIView와 같이 Intrinsic Content Size가 없는 view같은 경우는 placeholder 속성으로 임시적으로 사이즈를 정해줄 수 있습니다. 스토리보트에서만 적용되고, 앱의 실제 동작 중에는 적용되지 않습니다.

custom class

이러한 view의 경우 cocoa touch class를 만들어준 다음, Identity Inspector에서 Custom class로 연결해 줌으로써 Intrinsic content size를 정해 줄 수도 있습니다.👍

import UIKit

@IBDesignable
class MyView: UIView {

    override var intrinsicContentSize: CGSize {
        return CGSize(width: 50, height: 50)
    }

}
profile
i🍎S 개발을 합니다

0개의 댓글