티스토리 뷰

Auto layout을 통해 constraint를 잡을 때 반드시 해당 view의 위치(position)와 크기(size) 정보가 필요합니다.

하나라도 모르면 뷰가 어그러지거나, 화면 상에 보이지 않는 등 예상했던 것과 다르게 표현이 되곤하죠!

그런데 모든 뷰가 width/height 정보를 명시해 줄 필요는 없어요.

예를 들어 볼까요?

final class ViewController: UIViewController {
    
    private var label: UILabel = {
        let label = UILabel()
        label.text = "welcome back to my channel"
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.addSubview(label)
        
        NSLayoutConstraint.activate([
            label.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 10),
            label.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 10)
        ])
    }

}

"welcome back to my channel"이 적힌 label은 좌측상단에 10x10 만큼의 간격을 띄우고 표시 될거에요 아래처럼요.

크기 정보가 없는걸?!

 

그런데, leading과 top에 대한 위치 정보만 있고, 크기 정보가 없는데 잘 표현이 되었습니다?!

바로 UILabel의 intrinsic content size 덕분입니다.

Intrinsic Content Size

특정 뷰들은 자신들이 현재 갖고 있는 content에 따라 본질적으로 크기가 정해지기도 하는데 이 때 그 크기를 intrinsic content size

라고 해요. 아래 표에도 나와 있지만 조금 덧붙여보면

  • UIView, NSView : intrinsic content size 없음
  • Sliders : width 정해짐 (OS X 에서는 slider 종류에 따라 height도 정해지기도 함)
  • Label : 내부 텍스트 크기에 따라 width, height가 정해짐 (폰트도 당연히 영향 미침)
  • Button : button의 title과 갖고있는 margin에 따라 width, height 정해짐
  • image view : (image가 있다면) image 크기가 intrinsic content size가 됨
  • text view : intrinsic content size에 영향을 미치는 요소들이 많음(ex. content 길이, scroll 가능 여부 등)
    • scoll 이 가능하면 intrinsic content size 없음
    • scroll 이 불가능하면 line wrapping 적용 안된 text의 크기가 intrinsic content size

 

Content Hugging & Compression Resistance

Intrinsic content size와 함께 content hugging 과 compression resistance는 함께 나오는 개념이에요.

Intrinsic content sizie에 대해 제약조건을 추가할 수 있는 것이죠.

  Content Hugging Compression Resistance
Intrinsic content size의 최대값을 지정 최소값을 지정
존재 이유(?) view가 content를 알맞게 감싸기 위해 view가 content를 가리지 않게 하기 위해
default priority 250 750

 

 

위의 표에서 알 수 있다시피 compression resistance의 priority가 더 높아요.

그렇기 때문에 compression resistance를 통해 UI component를 늘리는 것이 더 권장됩니다.

물론 priority는 필요에 따라 수정이 가능하기 때문에 상황에 맞게 적절히 사용하면 되죠.

 

content hugging

아래 왼쪽 사진처럼 만들고 싶어서 코드를 다음과 같이 짰더니 결과가 오른쪽처럼 나와버렸어요.

NSLayoutConstraint.activate([
	titleLabel1.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 10),
	titleLabel1.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 10),
	titleLabel2.leadingAnchor.constraint(equalTo: titleLabel1.trailingAnchor,constant: 10),
	titleLabel2.lastBaselineAnchor.constraint(equalTo: titleLabel1.lastBaselineAnchor),
	titleLabel3.leadingAnchor.constraint(equalTo: titleLabel2.trailingAnchor, constant: 10),
	titleLabel3.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -10),
	titleLabel3.lastBaselineAnchor.constraint(equalTo: titleLabel1.lastBaselineAnchor)
])

Product label도 딱 알맞게 감싸줬으면 좋겠는데 말이죠.

content hugging이 view가 content를 최대한 잘 감싸주기 위해 존재하는 것이라고 앞에서 언급했습니다.

그렇기 때문에 content hugging prirority를 높여주면 잘 감싸주겠죠?

아래 코드를 추가해보면 원하는 바를 이룰 수 있어요.

titleLabel1.setContentHuggingPriority(.defaultHigh, for: .horizontal)
titleLabel2.setContentHuggingPriority(.defaultHigh, for: .horizontal)

 

compression resistance

아까 처음 짰던 코드로 아래와 같은 것을 표현하고 싶었지만 오른쪽과 같은 결과가 나왔어요.

compression resistance는 최대한 content가 짤리지 않게 표현되는 것이라고 말씀드렸어요.

그런데 뒤에 하나 더 나와야 할 label이 가운데 label 때문에 밀려서 표현이 안되었네요.

이럴 때 사용할 것이 compression resistance가 됩니다.

가운데 label의 compression resistance priority를 줄이고 세번째 label의 priority를 높이면 표현이 잘 되겠죠?

아래와 같이 코드를 추가하면 원하는 바를 이룰 수 있어요.

titleLabel2.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
titleLabel3.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)

출처

Anatomy of a Constraint

오토레이아웃으로 iOS 앱 쉽게 개발하기

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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 31
글 보관함