Tong's Blog

[Swift] Frame과 Bounds에 대해 알아보자 본문

iOS/Swift

[Swift] Frame과 Bounds에 대해 알아보자

통스 2020. 8. 4. 18:57
반응형

안녕하세요.

 

오늘은 UI요소들을 위치시키는데 사용하는 Frame와 Bounds에 대해 알아보겠습니다.

각각이 뜻하는 바가 무엇인지 알아보고 그 차이점과 사용법에 대해 정리하겠습니다.

 

1. Frame

정의를 아는 방법중에 가장 좋은 방법은 공식문서를 참고하는 것이겠죠.

https://developer.apple.com/documentation/uikit/uiview/1622621-frame

 

Apple Developer Documentation

 

developer.apple.com

저의 짧은 영어로 해석하자면 슈퍼뷰의 좌표계에서 뷰의 위치와 크기를 나타내는 사각형 형태의 틀이라고 합니다.

사각형 형태의 틀이라는 것은 딱보면 이해가 되는데 슈퍼뷰의 좌표계라는 말이 눈에 띄는 것 같습니다.

 

그럼 슈퍼뷰라는 것이 무엇을 뜻하는 것일까요?

상속관계에 대해 이해가 많으신 분이라면 짐작하셨겠지만 자기자신이 자식이라고 했을 때 부모가 되는 뷰를 슈퍼뷰라고 할 수 있고 쉽게 얘기한다면 해당 frame의 뷰를 가진 상위 뷰라고 생각하시면 됩니다.

 

그렇다면 뷰의 상위(슈퍼) 관계는 어떻게 이루어질까요?

let myView = UIView()

view.addSubview(myView)

코드로 UI를 짜시는 분이라면 많이 본 코드일텐데 스토리보드로 UI를 구현하시는 분이라면 생소할 수도 있겠네요.(스토리보드에서는 드래그 앤 드롭으로 다른 뷰 안에 또 다른 뷰를 생성했다고 보면 됩니다.)

 

우선, 우리는 여기서 2개의 UI Component들을 볼 수 있습니다.

  • view
  • myView

view는 우리가 생성할 수도 있겠지만 일반적으로 UIViewController를 생성하면 자동으로 생성되는 view이고

myView는 제가 UIView()로 생성한 새로운 View입니다.

 

코드에서 짐작하셨겠지만 addSubview를 통해 뷰를 포함시킬때(일반적으로 그릴 때 사용) 왼쪽에 있는 UI가 슈퍼뷰가 되고 오른쪽에 있는 UI가 자식뷰가 된다고 생각하시면 됩니다.

 

자 다시 frame으로 돌아와서 슈퍼뷰의 좌표계에서 위치와 크기를 나타내는 말을 생각해본다면 현재 내가 그리는 뷰의 frame을 지정한다는 것은 슈퍼뷰에 상대적으로 어느 위치에 있는지 그려준다는 것이다.

 

조금 더 이해가 쉽도록 프로젝트를 통해서 본다면

스토리보드를 통해 view안에 Green View를 Green View안에 Blue View를 생성했습니다.

아까 코드의 addSubview와 같은 역활을 드래그앤 드롭으로 손쉽게 구현됬습니다.

스토리보드에서 설정된 frame 수치(죄: Green View, 우: Blue View)

 

스토리 보드가 아닌 코드로 frame을 알아보기 위해 제가 샘플로 작성한 코드는 다음과 같습니다.

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var greenView: UIView!
    @IBOutlet weak var blueView: UIView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        blueView.frame = CGRect(x: 50, y: 50, width: 50, height: 50)
    }

}

 

각각의 뷰를 IBOutlet으로 연결했고(이미 스토리를 보드를 통해 addSubview는 구현된 상황) blueView의 frame을 제가 원하는대로 변형했습니다. 결과는 아래와 같습니다.

 

코드로 구현된 frame 결과

스토리보드와 코드로 짠 결과물을 보니 frame에 대한 감이 오시나요?

스토리보드에서는 Blue View가 Green View에 원점(왼쪽 위)에서 x축으로 0 y축으로 0만큼 이동한 지점에서 너비 100, 높이 100만큼의 지점을 가지게 되고

코드에서는 Green View의 x축으로 50 y축으로 50만큼 이동한 지점에서 너비 50, 높이 50만큼의 지점을 가지게 되기 때문에 각각의 결과가 나타난 것입니다.

 

그러면 다음으로 Bounds에 대해 알아보겠습니다.

 

2. Bounds

역시나 공식문서를 살펴보면

https://developer.apple.com/documentation/uikit/uiview/1622580-bounds

 

Apple Developer Documentation

 

developer.apple.com

설명에 보면 frame과 대부분의 설명이 일치하는데 다른 점은 "자기 자신의 좌표계에서" 위치와 사이즈를 결정한다. 라는 차이가 있네요.

 

역시나 프로젝트를 통해서 알아보겠습니다.

let yellowView: UIView = {
	let aView = UIView()
    aView.backgroundColor = .yellow
    return aView
}()
    
override func viewDidLoad() {
	super.viewDidLoad()
    // Do any additional setup after loading the view.
        
    //blueView.frame = CGRect(x: 50, y: 50, width: 50, height: 50)
    greenView.addSubview(yellowView)
    yellowView.frame = CGRect(x: 50, y: 50, width: 100, height: 100)
        
    //greenView.bounds = CGRect(x: 0, y: 250, width: 200, height: 200)
}

Yellow View라는 UIView를 새로 선언했고 해당 View를 기존에 있던 Green View의 Subview로 만들었습니다. 그리고 해당 뷰의 프레임을 위의 수치로 입력했습니다. 우선 해당 결과를 보시면

위와 같이 나타납니다.

 

여기까지는 크게 다른게 없습니다. 그렇다면 Yellow의 Bounds를 변경해보겠습니다.

yellowView.bounds = CGRect(x: 50, y: 50, width: 100, height: 100)

해당 코드를 viewDidLoad에 넣으면 어떤 일이 생길까요?

결과는 아까 보셨던 결과화면을 보시면 됩니다. 같기 때문이죠

 

왜 이런 일이 일어났을까요?

bounds는 자기 자신만 좌표계를 가지기 때문에 해당 값을 변화시켜도 자기 자신은 그 자리를 지킨다고 생각하시면 됩니다.

 

그렇다면 bounds의 변화를 어디서 볼 수 있을까요?

Yellow View가 아닌 Yellow의 슈퍼뷰인 Green View의 bounds를 변경시켜 보겠습니다.

greenView.bounds = CGRect(x: 0, y: 250, width: 200, height: 200)

결과는 아래와 같습니다.

Yellow View뿐만 아니라 frame을 설명하기 위해 사용했던 Blue View까지 저 위로 솟아올랐습니다.

왜 이런 결과가 나타난 것일까요?

 

우선 코드에서 사용한 수치들을 살펴본다면 뒤에 있는 width와 height는 사이즈와 관계있으므로 지금 상황에 필요없고(width와 height는 조절하면 크기는 정상적으로 조절됩니다. Green View든 Yellow View든) x는 0만큼 y를 250만큼 변화시켰는데 frame때와는 다르게 250을 변화시켰을 때 아래가 아닌 위로 올라가는 이유는 무엇일까요?

 

설명이 어려울 수도 있지만 bounds을 변화시키는 것은 view가 해당 위치로 이동했을 때 subView들의 위치를 다시 그려준다고 생각하시면 됩니다. 만약 y축으로 250만큼 Green View가 아래로 이동한다면 상대적으로 Yellow View(Blue View)는 위로 위치하게 됩니다. 하지만  bounds는 자기 자신의 좌표계에서 움직이지 않기 때문에 Green View는 그대로 있고 나머지 Subview들만 이동한 것같은 느낌을 주게 되는 것입니다.

 

해당 차이점을 이해하셨나요?

쉬운 내용은 아니지만 이해를 해두면 앞으로 우리가 사용할 CGRect및 Frame, bounds를 사용할 때 도움이 될 것 같습니다.

 

감사합니다.

 

P.S : 잘못된 부분에 대해서는 언제나 피드백 및 비판을 환영합니다.

반응형
Comments