문제

UIView 및 그 하위 클래스의 모든 속성 framebounds.차이점은 무엇입니까?

도움이 되었습니까?

해결책

그만큼 범위uiview 입니다 직사각형, 자체 좌표계 (0,0)에 대한 위치 (x, y) 및 크기 (너비, 높이)로 표현됩니다.

그만큼 액자uiview 입니다 직사각형, 내부에 포함 된 수퍼 뷰에 대한 위치 (x, y) 및 크기 (너비, 높이)로 표현됩니다.

따라서 수퍼 뷰의 25,25 (x, y)에 위치한 100x100 (너비 x 높이)의 크기를 가진 뷰를 상상해보십시오. 다음 코드는이보기의 한계와 프레임을 인쇄합니다.

// This method is in the view controller of the superview
- (void)viewDidLoad {
    [super viewDidLoad];

    NSLog(@"bounds.origin.x: %f", label.bounds.origin.x);
    NSLog(@"bounds.origin.y: %f", label.bounds.origin.y);
    NSLog(@"bounds.size.width: %f", label.bounds.size.width);
    NSLog(@"bounds.size.height: %f", label.bounds.size.height);

    NSLog(@"frame.origin.x: %f", label.frame.origin.x);
    NSLog(@"frame.origin.y: %f", label.frame.origin.y);
    NSLog(@"frame.size.width: %f", label.frame.size.width);
    NSLog(@"frame.size.height: %f", label.frame.size.height);
}

이 코드의 출력은 다음과 같습니다.

bounds.origin.x: 0
bounds.origin.y: 0
bounds.size.width: 100
bounds.size.height: 100

frame.origin.x: 25
frame.origin.y: 25
frame.size.width: 100
frame.size.height: 100

따라서 두 경우 모두, 우리가 경계 나 프레임을보고 있는지 여부에 관계없이보기의 너비와 높이가 동일하다는 것을 알 수 있습니다. 다른 점은 x, y 뷰의 위치입니다. 경계의 경우, X 및 Y 좌표는 0,0입니다.이 좌표는보기 자체와 관련이 있습니다. 그러나 프레임 x 및 y 좌표는 부모보기 내에서보기의 위치와 관련이 있습니다 (이전에 우리가 25,25 명이라고 말했습니다).

또 한있다 훌륭한 프레젠테이션 그것은 uiviews를 다루고 있습니다. 프레임과 경계의 차이를 설명 할뿐만 아니라 시각적 예를 보여주는 슬라이드 1-20을 참조하십시오.

다른 팁

짧은 대답

프레임 =뷰의 위치 및 크기를 사용하는 상기 시스템의 좌표

  • 중요:을 두기에 부모

범위 =뷰의 위치 및 크기 사용 그것의 자신의 조정 시스템

  • 중요:배기 컨텐츠 또는 하위 자체 내에서

자세한 응답

하는 데 도움이 나를 기억 프레임, 의 사진 프레임에는 벽이.사진 프레임은 같은 국경의 보기입니다.내가 걸 수 있는 어느 곳에서나 사진하고 싶다.동일한 방식으로 넣을 수 있는 뷰가 어디서나 내가 원하는 부모 뷰 내에서(또는 뷰).상기와 같다.은 좌표계의 원점에서 왼쪽 상단에 있습니다.우리는 우리의 보기에는 원산지의 뷰를 설정하여 보기 프레임의 x-y 좌표를(0,0)처럼 거의 그림에서 매우 왼쪽 상단 모서리의 벽입니다.그것을 이동하는 권리를 증가,x,이동하는것은 아래로 늘 y.

하는 데 도움이 나를 기억 범위, 의 농구 코트 는 때때로 농구되는 범위를 벗어.당신은 드리블을 통해 모든 농구 코트,하지만 당신이 정말로 걱정하지 않는 법원은 그 자체이다.그것은에 있는 체육관,또는 외부에서 고등학교 또는 당신의 집 앞에.그것은 중요하지 않습니다.당신만 원하는 농구를 재생합니다.같은 방법으로,좌표계에 대해 보고의 범위에 대한 관심 뷰 자체.그것에 대해 아무것도 몰디에 위치하고 있 부모 뷰.경계'origin(점(0,0)의 기본값)이의 왼쪽 상단 모서리합니다.어떤 하위는 이 보기에는 배치에 관련하여 이점이다.그것은 다음과 같이 복용의 농구 전면 왼쪽의 코트도 있습니다.

지금 이 혼란을 제공하려고 할 때 비교 프레임과 범위.실제로 그것이 나쁘지 않으로 보인다 처음에는,하지만.자의 사용 일부 사진을 이해하는 데 도움이.

프레임 vs 범위

에서 첫 번째 사진 왼쪽에 우리가 볼 수 있는 위쪽에서 왼쪽의 부모 보기입니다. 노란색 사각형을 나타내 보기 프레임입니다. 오른쪽에 우리는 다시 볼 수 있지만 이번 부모 뷰가 표시되지 않습니다.는 범위에 대해 알고하지 않고 부모 보기입니다. 녹색 사각형을 나타내 보기습니다.red dot 에서 모두 이미지를 나타내 원산지 프레임의 또는 경계.

Frame
    origin = (0, 0)
    width = 80
    height = 130

Bounds 
    origin = (0, 0)
    width = 80
    height = 130

enter image description here

그래서 구조와 범위를 정확히 동일하다는 사진입니다.자 예를 살펴보고 그들은 다릅니다.

Frame
    origin = (40, 60)  // That is, x=40 and y=60
    width = 80
    height = 130

Bounds 
    origin = (0, 0)
    width = 80
    height = 130

enter image description here

그래서 당신이 볼 수 있는 변화하는 x-y 좌표를 프레임의 움직임은 부모에서 보기입니다.하지만 내용 보기의 자체 여전히 보이는 정확히 동일합니다.경계 없는 아이디어 아무것도가 다릅니다.

지금까지의 너비와 높이 모두 구조와 범위로 되었을 정확히 동일합니다.지 않는 항상 진실하다,하지만.보면 어떻게 우리를 회전합 보기 20 개 도시계 방향으로 돌립니다.(회전이 사용하여 수행으로 변환합니다.보 문서보기층 예 자세한 정보는.)

Frame
    origin = (20, 52)  // These are just rough estimates.
    width = 118
    height = 187

Bounds 
    origin = (0, 0)
    width = 80
    height = 130

enter image description here

당신이 볼 수 있는 경계를 아직도 동일합니다.그들은 여전히 아무것도 몰라 일어났습니다!프레임의 값이 있는 모든 변경,하지만.

지금은 좀 더 쉽게 사이의 차이를 확인하려면 프레임과 범위,그렇지 않나요?문서 당신은 아마 이해 하지 않는 프레임과 범위 을 정의합 보기 프레임으로

...가장 작은 경계 상자의 보기와 관련하여 그것은 부모 좌표 시스템 등 어떤 변환을 적용하는 뷰입니다.

그것은 주목하는 것이 중요하신 경우는 변환기,다음 프레임된 정의되지 않습니다.그래서 실제로,옐로우 프레임에는 그렸던 주위를 회전 녹색 경계에서 위의 이미지를 실제로 존재합니다.는 것을 의미하는 경우 당신은 회전,규모 또는 어떤 다른 변환을 다음 사용하지 않아야 프레임의 값이다.여전히 사용할 수 있습 범위 값을,하지만.Apple 문서 경고:

중요: 면 뷰의 transform 속성을 포함하지 않습 id 변환,프레임에는 뷰가 정의되지 않고 그래서는 결과 그것의 자동 크기 동작을 지원합니다.

오히려 불행한 일이에 대해 자동으로 크기가 조정....뭔가 할 수 있습니다,하지만.

Apple docs 상태:

을 수정할 때 transform 재산의 보고,모든 변환은 수행 중심을 기준으로점 보기입니다.

그래서 당신이 경우에 이동해야기 주위에서는 부모 후 변환 작업이 완료되면,당신은 그것을 할 수 있는 변경하여 view.center 좌표입니다.아 frame, center 사용 좌표계의 부모 뷰.

Ok,let's get rid 우리의 회전과 범위.지금까지 그 범위를 기원은 항상에 머물렀(0,0)입니다.그것은이없는,하지만.어떤 경우에 우리의 보기에는 큰 하위 보기에는 너무 크게 표시가?우리는 그것을 UIImageView 큰 이미지입니다.여기 우리의 그림이 두 번째 위에서 다시지만,이번에 우리가 볼 수 있습니다 무엇의 전체 내용을 우리의 보기의 하위 보기 것처럼 보인다.

Frame
    origin = (40, 60)
    width = 80
    height = 130

Bounds 
    origin = (0, 0)
    width = 80
    height = 130

enter image description here

단지 왼쪽 상단의 이미지 안에 들어갈 수 있는 뷰의 범위.지금 보기면 어떻게 되는 변경의 범위'origin 좌표입니다.

Frame
    origin = (40, 60)
    width = 80
    height = 130

Bounds 
    origin = (280, 70)
    width = 80
    height = 130

enter image description here

프레임지지 않았으로 이동는 데 도움이지만 내용 내부 프레임의 변경되었기 때문에 원산지의 경계 직사각형에서 시작한 다른 부분에게 확인할 수 있게 되었습니다.이것은 전체적인 아이디어 뒤에 UIScrollView 그것은 서브 클래스(예를 들어, UITableView).보 이해 UIScrollView 에 대한 자세한 설명.

을 사용하는 경우 프레임과할 때 사용하는 범위

frame 관련 뷰의 위치에서 부모 볼,당신은 그것을 사용할 때 만들기 바깥쪽으로 변경, 을 변경하는 것처럼,그것의 폭 또는를 찾는 사이의 거리 보기 및 상단의 상위기.

bounds안쪽으로 변경,그림 같은 것 또는 배열 하위 내에서 보기입니다.또한 사용의 범위의 크기를 얻으려면 뷰가 있는 경우 일부 transfomation 니다.

에 대한 기사 또한 연구:

애플 문서

관련 유래 질문

다른 자원

자신을 연습

를 읽는 것 외에도 위의 기사를,그것은 나에게 많은 도움이하 테스트 응용 프로그램입니다.할 수 있습 뭔가를 시도와 비슷합니다.(나는 아이디어에서 이 비디오는 물론 그러나 불행하게도 그것은 무료로하지 않습니다.)

enter image description here

는 코드는 다음과 같습니다 당신의 참고를 위한:

import UIKit

class ViewController: UIViewController {


    @IBOutlet weak var myView: UIView!

    // Labels
    @IBOutlet weak var frameX: UILabel!
    @IBOutlet weak var frameY: UILabel!
    @IBOutlet weak var frameWidth: UILabel!
    @IBOutlet weak var frameHeight: UILabel!
    @IBOutlet weak var boundsX: UILabel!
    @IBOutlet weak var boundsY: UILabel!
    @IBOutlet weak var boundsWidth: UILabel!
    @IBOutlet weak var boundsHeight: UILabel!
    @IBOutlet weak var centerX: UILabel!
    @IBOutlet weak var centerY: UILabel!
    @IBOutlet weak var rotation: UILabel!

    // Sliders
    @IBOutlet weak var frameXSlider: UISlider!
    @IBOutlet weak var frameYSlider: UISlider!
    @IBOutlet weak var frameWidthSlider: UISlider!
    @IBOutlet weak var frameHeightSlider: UISlider!
    @IBOutlet weak var boundsXSlider: UISlider!
    @IBOutlet weak var boundsYSlider: UISlider!
    @IBOutlet weak var boundsWidthSlider: UISlider!
    @IBOutlet weak var boundsHeightSlider: UISlider!
    @IBOutlet weak var centerXSlider: UISlider!
    @IBOutlet weak var centerYSlider: UISlider!
    @IBOutlet weak var rotationSlider: UISlider!

    // Slider actions
    @IBAction func frameXSliderChanged(sender: AnyObject) {
        myView.frame.origin.x = CGFloat(frameXSlider.value)
        updateLabels()
    }
    @IBAction func frameYSliderChanged(sender: AnyObject) {
        myView.frame.origin.y = CGFloat(frameYSlider.value)
        updateLabels()
    }
    @IBAction func frameWidthSliderChanged(sender: AnyObject) {
        myView.frame.size.width = CGFloat(frameWidthSlider.value)
        updateLabels()
    }
    @IBAction func frameHeightSliderChanged(sender: AnyObject) {
        myView.frame.size.height = CGFloat(frameHeightSlider.value)
        updateLabels()
    }
    @IBAction func boundsXSliderChanged(sender: AnyObject) {
        myView.bounds.origin.x = CGFloat(boundsXSlider.value)
        updateLabels()
    }
    @IBAction func boundsYSliderChanged(sender: AnyObject) {
        myView.bounds.origin.y = CGFloat(boundsYSlider.value)
        updateLabels()
    }
    @IBAction func boundsWidthSliderChanged(sender: AnyObject) {
        myView.bounds.size.width = CGFloat(boundsWidthSlider.value)
        updateLabels()
    }
    @IBAction func boundsHeightSliderChanged(sender: AnyObject) {
        myView.bounds.size.height = CGFloat(boundsHeightSlider.value)
        updateLabels()
    }
    @IBAction func centerXSliderChanged(sender: AnyObject) {
        myView.center.x = CGFloat(centerXSlider.value)
        updateLabels()
    }
    @IBAction func centerYSliderChanged(sender: AnyObject) {
        myView.center.y = CGFloat(centerYSlider.value)
        updateLabels()
    }
    @IBAction func rotationSliderChanged(sender: AnyObject) {
        let rotation = CGAffineTransform(rotationAngle: CGFloat(rotationSlider.value))
        myView.transform = rotation
        updateLabels()
    }

    private func updateLabels() {

        frameX.text = "frame x = \(Int(myView.frame.origin.x))"
        frameY.text = "frame y = \(Int(myView.frame.origin.y))"
        frameWidth.text = "frame width = \(Int(myView.frame.width))"
        frameHeight.text = "frame height = \(Int(myView.frame.height))"
        boundsX.text = "bounds x = \(Int(myView.bounds.origin.x))"
        boundsY.text = "bounds y = \(Int(myView.bounds.origin.y))"
        boundsWidth.text = "bounds width = \(Int(myView.bounds.width))"
        boundsHeight.text = "bounds height = \(Int(myView.bounds.height))"
        centerX.text = "center x = \(Int(myView.center.x))"
        centerY.text = "center y = \(Int(myView.center.y))"
        rotation.text = "rotation = \((rotationSlider.value))"

    }

}

아래 코드를 실행하십시오

- (void)viewDidLoad {
    [super viewDidLoad];
    UIWindow *w = [[UIApplication sharedApplication] keyWindow];
    UIView *v = [w.subviews objectAtIndex:0];

    NSLog(@"%@", NSStringFromCGRect(v.frame));
    NSLog(@"%@", NSStringFromCGRect(v.bounds));
}

이 코드의 출력은 다음과 같습니다.

케이스 장치 방향은 초상화입니다

{{0, 0}, {768, 1024}}
{{0, 0}, {768, 1024}}

케이스 장치 방향은 조경입니다

{{0, 0}, {768, 1024}}
{{0, 0}, {1024, 768}}

분명히 프레임과 경계의 차이점을 볼 수 있습니다.

그만큼 액자 Uiview를 정의하는 사각형입니다 수퍼 뷰에 대한 존중.

그만큼 경계 rect 그것을 정의하는 값의 범위입니다 NSView의 좌표계.

즉,이 사각형의 모든 것이 실제로 UIView에 표시됩니다.

프레임 은 근원(왼쪽 상단 코너)및 크기 보기에 그것의 최고 보기 의 좌표계,이것은 당신이 번역 보기에 그것의 최고 보기로 프레임을 변경하는 원산지 범위 다른 한편으로는 크기 그리고 원산지에서 자신의 좌표계,이렇게 기본적으로 경계 원점(0,0).

대부분의 시간 프레임과 범위는 적합하지만,당신의 프레임((140,65),(200,250))고 경계((0,0),(200,250))예를 들어 아기자기하고 기울이 그래서 그 스탠드 오른쪽 하단 모서리,그 경계를 아직도((0,0),(200,250)) , 하지만 프레임지 않습니다.

enter image description here

프레임 있는 가장 작은 사각형 캡슐화/주변 보기 프레임(사진에서와 같이)될 것입((140,65),(320,320)).

또 다른 차이점은 예를 들어 있는 경우는 데 도움은 그 범위에는((0,0),(200,200))그리고 이는 데 도움이 서브뷰는 프레임((20,20),(100,100))및 변경할 수퍼 뷰 경계((20,20),(200,200)) , 다음 하위 보기 프레임에 여전히 있을 것입니다((20,20),(100,100))그러나 offseted 여(20,20)기 때문에 그리는 데 도움 좌표 시스템 offseted 여(20,20).

이 도움이 되었으면 좋겠습니다 누군가 있습니다.

NSVIEW와 관련된 경계는 수퍼 뷰에 상대적으로 연결됩니다.

예 : x = 40, y = 60.

FRAME

BOUNDS

위의 답변은 경계와 프레임의 차이를 잘 설명했습니다.

경계 : 자체 좌표계에 따라보기 크기와 위치.

프레임 : 수퍼 뷰와 관련된보기 크기 및 위치.

그러면 x의 경계의 경우 y는 항상 "0"이라는 혼란이 있습니다. 이것은 사실이 아닙니다. 이것은 uiscrollview 및 uicollectionview에서도 이해할 수 있습니다.

Bounds 'x, y는 0이 아닙니다.
우리에게 uiscrollview가 있다고 가정 해 봅시다. 우리는 Pagination을 구현했습니다. UiscrollView에는 3 페이지가 있으며 내용의 너비는 화면 너비가 3 배입니다 (Screenwidth가 320이라고 가정). 높이는 일정합니다 (200을 가정).

scrollView.contentSize = CGSize(x:320*3, y : 200)

세 가지 uiimageviews를 하위 뷰로 추가하고 자세히 살펴보십시오. 엑스 프레임의 가치

let imageView0 = UIImageView.init(frame: CGRect(x:0, y: 0 , width : scrollView.frame.size.width, height : scrollView.frame.size.height))
let imageView1 :  UIImageView.init( frame: CGRect(x:320, y: 0 , width : scrollView.frame.size.width, height : scrollView.frame.size.height))
let imageView2 :  UIImageView.init(frame: CGRect(x:640, y: 0 , width : scrollView.frame.size.width, height : scrollView.frame.size.height))
scrollView.addSubview(imageView0)
scrollView.addSubview(imageView0)
scrollView.addSubview(imageView0)
  1. Page 0 : 스크롤 뷰가 0 페이지에있을 때 경계는 다음과 같습니다.(X : 0, y : 0, 너비 : 320, 높이 : 200)

  2. 1 페이지 : 스크롤하여 1 페이지로 이동합니다.
    이제 한계가 될 것입니다 (X : 320, y : 0, 너비 : 320, 높이 : 200)우리는 자체 좌표계와 관련하여 말했습니다. 이제 스크롤 뷰의 "가시 부분"에는 320에 "x"가 있습니다. ImageView1의 프레임을보십시오.

  3. 2 페이지 : 스크롤하여 2 페이지로 이동합니다경계 : (x : 640, y : 0, 너비 : 320, 높이 : 200)다시 imageView2의 프레임을 살펴보십시오

uicollectionView의 경우와 동일합니다. CollectionView를 보는 가장 쉬운 방법은 스크롤하고 해당 경계를 인쇄/로그인하면 아이디어를 얻는 것입니다.

위의 모든 답변은 정확하며 이것은 다음과 같습니다.

프레임과 경계 개념을 구별하려면 개발자가 다음을 읽어야합니다.

  1. 수퍼 뷰 (한 부모보기)와 관련하여 = 프레임 내에 포함됩니다.
  2. 자체 좌표계와 관련하여 하위 뷰 위치 = 경계를 결정합니다.

"바운드"는 좌표가 설정된 시야의 위치라는 인상을주기 때문에 혼란 스럽습니다. 그러나 이것들은 관계에 있으며 프레임 상수에 따라 조정됩니다.

iPhone screen

프레임 = 부모보기 좌표계를 사용한 뷰의 위치 및 크기

bounds = 자체 좌표계를 사용하여보기의 위치 및 크기

뷰는 프레임 사각형과 경계 사각형의 두 개의 직사각형을 사용하여 크기와 위치를 추적합니다. 프레임 사각형은 Superview의 좌표계를 사용하여 슈퍼 뷰에서보기의 위치와 크기를 정의합니다. 경계 사각형은 원점 및 스케일링을 포함하여보기의 내용을 그릴 때 사용되는 내부 좌표계를 정의합니다. 그림 2-1은 왼쪽의 프레임 사각형과 오른쪽의 경계 사각형 사이의 관계를 보여줍니다.”

요컨대, 프레임은 Superview의보기에 대한 아이디어이며, 경계는 뷰 자신의 아이디어입니다. 각보기마다 하나의 여러 좌표계를 갖는 것이 뷰 계층의 일부입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top