[iOS] frame과 bounds의 차이점 이해

11902 단어 XcodeiOSSwiftSwift5
「frame과 bounds의 차이는 뭐야!」가 되었기 때문에 조사했습니다.

원래 프레임과 바운드는



UIView의 서브 클래스가 가지는 프로퍼티. CGRect를 반환합니다.

영어 단어의 의미 적으로 Weblio 영어 사전에 따르면

frame



a 창틀.
b 액자.
c 배경.
d (온상) 프레임 워크, 프레임, 온상.
e (자수 (시시유) 등) 제작대, 걸쇠 프레임.
f 복수의 프레임 (안경), 프레임.
g (양봉 제거 가능) 상자 모양의 프레임.

요컨대 "틀"이라는 의미(?)

bounds



1 경계, 한계 (내부); 출입 허가 지역.
2 한도, 범위; 경계선, 한계

라는 의미다

CGRect란?



공식 문서에 따르면

A structure that contains the location and dimensions of a rectangle.

로 정의되며,
의역하면
구형의 치수를 돌려주는 구조체가 됩니다.

frame과 bounds의 차이는



원래 frame과 bounds가 누군가를 알았으므로, 드디어 본제입니다.

frame



요소 자신을 기준으로 한 상대 좌표 및 크기를 반환하는 속성 (superview 기준)

bounds



요소의 부모를 기준으로 한 상대 좌표 및 크기를 반환하는 속성 (UIView 자체가 기준)

라는 차이가 있는 것 같습니다.

즉 어디를 기준으로 할지가 바뀌어 오는 것 같습니다.

샘플 코드



실제로 코드를 작성하고 검증합니다.
x: 200, y: 200에 正岡子規의 이미지를 배치하여 frame과 bounds의 값의 차이를 봅니다.

ViewController.swift
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let imageView = UIImageView(image: UIImage(named: "shiki"))

        // 指定した座標・大きさを設定
        imageView.frame = CGRect(x: 200, y: 200, width: 100, height: 100);

        print(
            "frameから見たX\(imageView.frame.minX)\n",
            "frameから見たY\(imageView.frame.minY)\n",
            "boundsから見たX\(imageView.bounds.minX)\n",
            "boundsから見たY\(imageView.bounds.minY)\n"
        )

        // viewにUIImageViewを追加
        self.view.addSubview(imageView)
    }

}



이 위치에 마사오카 코규가있을 때 결과는


이렇게 되었습니다.

좌표는 부모 요소를 frame에서 보면(200, 200) 곳에, 요소 자신을 기준으로 bounds에서 보면 (0, 0)으로 기준에 따라 다른 것에 대해서 크기는 함께 하는 것을 알 수 있습니다.

활용 예



부모 요소를 기준으로 자식 요소의 크기를 지정할 수 있습니다.
또, 이런 경우는 frame보다 bounds를 사용하는 편이 좋습니다. bounds는 요소 자신을 기준으로 한 좌표와 크기를 가지고 있기 때문입니다.
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let imageView = UIImageView(image: UIImage(named: "shiki"))

        // 大きさ(親要素の半分の正方形)
        imageView.frame.size = CGSize(width: view.bounds.width / 2, height: view.bounds.height / 2)

        // 中心の座標(親要素の中心をframeから取る)
        imageView.center = CGPoint(x: view.bounds.width / 2, y: view.bounds.height / 2)

        // viewにUIImageViewを追加
        self.view.addSubview(imageView)
    }

}

주의점



또, UIView를 확대·축소하거나, 회전시키면 frame의 값은 바뀌지만, bounds의 값은 바뀌지 않습니다

    override func viewDidLoad() {
        super.viewDidLoad()
        let rectangle = UIView(frame: .zero)
        rectangle.backgroundColor = .blue
        rectangle.frame.size = CGSize(width: 100, height: 200)
        rectangle.center = CGPoint(x: view.bounds.width / 2, y: view.bounds.height / 2)
        // 拡大前
        print(rectangle.frame, rectangle.bounds) // (157.0, 348.0, 100.0, 200.0) (0.0, 0.0, 100.0, 200.0)

        rectangle.transform = CGAffineTransform(scaleX: 2, y: 2)

        // 拡大後
        print(rectangle.frame, rectangle.bounds) // (107.0, 248.0, 200.0, 400.0) (0.0, 0.0, 100.0, 200.0)

        view.addSubview(rectangle)
    }

이와 같이 스케일 한 후, frame의 값은 변화하고 있는 것에 대해, bounds의 값이 변화하고 있지 않는 것을 알 수 있습니다.

참고문헌


  • What’s the difference between frame and bounds?
  • UIView 프레임 및 바운드 및 센터
  • Weblio 영어
  • 좋은 웹페이지 즐겨찾기