article thumbnail image
Published 2023. 1. 21. 23:02
"Frame-Based Layout"Programmatically하게 view들의 frame을 지정해주는 방식이다.

Frame

"Frame Rectangle"은 superView로부터 view의 location과 size를 정의한다.

var frame: CGRect { get set }


frame은 CGRect 타입의 변수인데,
CGRect은 location을 저장할 수 있는 origin프로퍼티와
size를 정의할 수 있는 size 프로퍼티가 존재한다.

public struct CGRect {

    public init()

    public init(origin: CGPoint, size: CGSize)

    public var origin: CGPoint

    public var size: CGSize
}


이때 정의한 frame의 origin은 좌상단의 좌표로
superView의 origin을 (0,0)으로 두고 origin으로부터 얼마나 떨어져 있는지 나타낸다.

위와 같은 경우, second View의 frame.origin은 (50, 60)이 된다.

따라서, 해당 origin을 기준으로 width height만큼 view를 그린다.

frame을 변경할 경우 draw(_:) 메서드의 호출 없이 자동적으로 redisplay된다.

contentMode에 redraw 옵션을 주게 되면, setNeedsDisplay()메서드를 통해 다음 view update cycle에
draw(_:) 메서드를 통해 다시 그려지게 된다.

secondView.contentMode = .redraw

vs. bounds

흔히 bounds와 frame을 헷갈려 하는데, 이들의 차이점에 대해 추가적으로 알아보자.

  • frame : superView로부터 view의 location과 size를 정의
  • bounds : 자신만의 좌표계로부터 location과 size를 정의

bounds는 자신만의 좌표계에서 location이 정의되기 때문에, origin은 (0,0)이 된다.

size 개념에서 살펴보면,
frame은 view를 그리기 위해 감싸는 사각형이고,
bounds는 view 자체를 감싸는 사각형이 된다.

이들은 default하게 origin을 제외하고 size는 같지만, transform을 적용하게 되면 달라지는 것을 볼 수 있다.

따라서, rotation을 진행했을 때, frame의 origin과 size가 변하게 된다.

또한, origin 개념에서 살펴보게 되면,
bounds viewPort 혹은 창문이라고 생각하면된다.
bounds의 origin을 이동하는 것은 창문을 이동하는 것과 같이 내부에 보여지는 subView들이 이동하게 된다.

더 엄밀히 말하자면, subView나 frame이나, bounds가 변하는 것이 아니라,
해당 view의 bounds를 변화 함으로써 subView를 보는 시점을 변경한 것이다.

다음과 같은 screen에 second View라는 창문이 있다고 생각하면,

second View의 bounds.origin을 이동하는 것은 다음과 같다.

따라서, third View를 이동하는 것과 같이 보이게 된다.

AutoResizingMask

frame을 programmatically하게 정의하는 "Frame-based Layout" 방식은
변경이 일어나면 원하는 대로 변경이 가능하기에 flexibility 하고 성능이 좋다.

하지만, view의 사이즈가 변할 때마다 subView의 위치나 사이즈를 직접 지정해야 하기 때문에, 유지보수 및 디버그에 대한 cost가 높다.

autoresizing mask를 통해 이러한 단점을 완하 시킬 수 있는데,
autoresizing masksuperView의 size(bounds의 size)가 변할 때마다
자동으로 옵션에 따라 resize해주는 integer bit mask이다.

옵션에 관한 자세한 내용은 공식문서에서 더 자세히 볼 수 있다.

thirdView.autoresizingMask = [.flexibleHeight, .flexibleWidth]

Reference

Apple Documentation

복사했습니다!