iOS/UIKit

[UIKit] PinLayout이란

Dev_Ted 2025. 7. 30. 21:03

PinLayout

“No Auto layout constraints attached”

 

PinLayout은 오토 레이아웃을 사용하지 않고, 뷰의 레이아웃을 수동으로 정의하는 라이브러리로, UIStackView, 오토 레이아웃보다 뷰의 렌더링 속도가 훨씬 빠른 레이아웃 방식입니다.

특징

  • 문법적으로 간결함
  • addSubview까지 진행해야 함
  • 수동으로 레이아웃 (오토 레이아웃에 의존하지 않음)
    • 그렇다고 둘을 같이 쓰면 안되는 것은 아님
  • Full Control
    • 기기, traitCollection, animation에 따른 조건문, 반복문 추가 가능
  • 간단하고 빠르게 동작하기 위해 존재함
  • Stateless
    • UIView에 저장 프로퍼티를 추가하지 않고, view의 frame 프로퍼티를 계산
    • Stateless하기 때문에 다른 프레임워크와 충돌하지 않고 사용할 수 있음
  • No Auto Layout, Constraints
    • Priority도 없음
  • view의 현재 frame을 기준으로 시작하기 때문에, 초기화 시점에 view의 크기를 설정하고, 그 뒤에 view의 위치를 설정할 수 있음 ⇒ 애니메이션 친화적으로 만들어줌
    • 크기를 초기화하고 위치를 바꾸면 애니메이션 효과가 나타남
  • 복잡하지 않음
    • UIView.pin, UIView.anchor, UIView.edge 프로퍼티만 사용

 

Layout

  • 드로잉 사이클에서 내부 레이아웃이 배치된 이후에 사용해야 함
  • 수동으로 레이아웃을 지정하기 때문에 디바이스 회전, 컨테이너 크기의 변경을 하기 위해선 UIView.layoutSubviews() 또는 UIViewController.viewDidLayoutSubviews() 내부에서 레이아웃을 업데이트 해야 함
  • 수동 레이아웃은 View의 크기와 위치를 직접 계산해야 하기 때문에, 그 정보가 확정되는 시점(layoutSubviews)에서만 정확한 레이아웃이 가능

 

Edges Layout

superview edges를 기준으로 뷰의 edge의 위치를 지정할 수 있음

Example

viewA.pin.top(10).bottom(10).left(10).right(10)
view.pin.all(10)

 

Layout multiple edges

여러 edge를 통해 레이아웃을 지정할 수 있음

Example

viewA.pin.topRight().size(100)
viewA.pin.top().right().size(100)

 

 

Relative Edges layout

다른 view와의 상대적인 위치를 기반으로도 레이아웃 설정 가능

Example

viewC.pin.top().after(of: viewA).before(of: viewB).margin(10)
viewC.pin.top().left(to: ViewA.edge.right).right(to: viewB.edge.left).margin(10)
viewC.pin.horizontallyBetween(viewA, and: viewB, aligned: .top).marginHorizontal(10)

 

a.pin.below(of: [imageView, label], aligned: left).right(to: label.edge.right).marginTop(10)

 

Layout Between other views

다른 view들 사이를 기준으로 레이아웃을 지정할 수 있음

Example

view.pin.horizontallyBetween(viewA, and: viewB).top(10).marginHorizontal(5)
view.pin.after(of: viewA).before(of: viewB).top(10).marginHorizontal(5)

 

Layout between other views with alignment

Example

view.pin.verticallyBetween(viewA, and: viewB, aligned: .center).marginVertical(10)

 

Edges

다른 view의 edge를 가리킬 때 사용할 수 있음

Example

aView.pin.top(to: bView.edge.top).hCenter(to: bView.edge.hCenter).marginTop(10)

 

 

Anchors

다른 view의 anchor를 가리킬 때 사용할 수 있음

Example

viewB.pin.center(to: viewA.anchor.topRight)

 

viewC.pin.topLeft(to: viewA.anchor.topRight).bottomAnchor(to: viewB.anchor.bottomLeft).marginHorizontal(10)
viewC.pin.horizontallyBetween(viewA, and: viewB, aligned: .top).height(of: viewA).marginHorizontal(10)

 

Aspect Ratio

비율을 통해 지정할 수 있음

imageView.pin.top().hCenter().width(50%).aspectRatio()

 

 

WrapContent

subview의 width와 height을 묶어줌

label.pin.below(of: imageView, aligned: .center).marginTop(4)
containerView.pin.wrapContent(padding: 10).center()

 

한 줄 요약

PinLayout은 오토 레이아웃을 대체하기 위한 라이브러리
728x90