UIView
and its subclasses all have the properties frame
and bounds
. What's the difference?
相关问题
- Image loads in simulator but not device?
- Unable to change UISearchBar cancel button title c
- NSOutlineView drag line stuck + blue border
- UIModalTransitionStyleFlipHorizontal flips Vertica
- Xcode4 templates now use underscore on iVars?
相关文章
- Xcode: Is there a way to change line spacing (UI L
- Converting (u)int64_t to NSNumbers
- Can keyboard of type UIKeyboardTypeNamePhonePad be
- “getter” keyword in @property declaration in Objec
- How to get a CGImageRef from Context-Drawn Images?
- NSMenuItem KeyEquivalent “ ”(space) bug
- Why are my UIView layer properties not being set w
- create UIImageView
The bounds of an UIView is the rectangle, expressed as a location (x,y) and size (width,height) relative to its own coordinate system (0,0).
The frame of an UIView is the rectangle, expressed as a location (x,y) and size (width,height) relative to the superview it is contained within.
So, imagine a view that has a size of 100x100 (width x height) positioned at 25,25 (x,y) of its superview. The following code prints out this view's bounds and frame:
And the output of this code is:
So, we can see that in both cases, the width and the height of the view is the same regardless of whether we are looking at the bounds or frame. What is different is the x,y positioning of the view. In the case of the bounds, the x and y coordinates are at 0,0 as these coordinates are relative to the view itself. However, the frame x and y coordinates are relative to the position of the view within the parent view (which earlier we said was at 25,25).
There is also a great presentation that covers UIViews. See slides 1-20 which not only explain the difference between frames and bounds but also show visual examples.
Frame its relative to its SuperView whereas Bounds relative to its NSView.
Example:X=40,Y=60.Also contains 3 Views.This Diagram shows you clear idea.
Short Answer
frame = a view's location and size using the parent view's coordinate system
bounds = a view's location and size using its own coordinate system
Detailed Answer
To help me remember frame, I think of a picture frame on a wall. The picture frame is like the border of a view. I can hang the picture anywhere I want on the wall. In the same way, I can put a view anywhere I want inside a parent view (also called a superview). The parent view is like the wall. The origin of the coordinate system in iOS is the top left. We can put our view at the origin of the superview by setting the view frame's x-y coordinates to (0, 0), which is like hanging our picture in the very top left corner of the wall. To move it right, increase x, to move it down increase y.
To help me remember bounds, I think of a basketball court where sometimes the basketball gets knocked out of bounds. You are dribbling the ball all over the basketball court, but you don't really care where the court itself is. It could be in a gym, or outside at a high school, or in front of your house. It doesn't matter. You just want to play basketball. In the same way, the coordinate system for a view's bounds only cares about the view itself. It doesn't know anything about where the view is located in the parent view. The bounds' origin (point (0, 0) by default) is the top left corner of the view. Any subviews that this view has are laid out in relation to this point. It is like taking the basketball to the front left corner of the court.
Now the confusion comes when you try to compare frame and bounds. It actually isn't as bad as it seems at first, though. Let's use some pictures to help us understand.
Frame vs Bounds
In the first picture on the left we have a view that is located at the top left of its parent view. The yellow rectangle represents the view's frame. On the right we see the view again but this time the parent view is not shown. That's because the bounds don't know about the parent view. The green rectangle represents the view's bounds. The red dot in both images represents the origin of the frame or bounds.
So the frame and bounds were exactly the same in that picture. Let's look at an example where they are different.
So you can see that changing the x-y coordinates of the frame moves it in the parent view. But the content of the view itself still looks exactly the same. The bounds have no idea that anything is different.
Up to now the width and height of both the frame and the bounds have been exactly the same. That isn't always true, though. Look what happens if we rotate the view 20 degrees clockwise. (Rotation is done using transforms. See the the documentation and these view and layer examples for more information.)
You can see that the bounds are still the same. They still don't know anything has happened! The frame values have all changed, though.
Now it is a little easier to see the difference between frame and bounds, isn't it? The article You Probably Don't Understand frames and bounds defines a view frame as
It is important to note that if you transform a view, then the frame becomes undefined. So actually, the yellow frame that I drew around the rotated green bounds in the image above never actually exists. That means if you rotate, scale or do some other transformation then you shouldn't use the frame values any more. You can still use the bounds values, though. The Apple docs warn:
Rather unfortunate about the autoresizing.... There is something you can do, though.
The Apple docs state:
So if you do need to move a view around in the parent after a transformation has been done, you can do it by changing the
view.center
coordinates. Likeframe
,center
uses the coordinate system of the parent view.Ok, let's get rid of our rotation and focus on the bounds. So far the bounds origin has always stayed at (0, 0). It doesn't have to, though. What if our view has a large subview that is too big to display all at once? We'll make it a
UIImageView
with a large image. Here is our second picture from above again, but this time we can see what the whole content of our view's subview would look like.Only the top left corner of the image can fit inside the view's bounds. Now look what happens if we change the bounds' origin coordinates.
The frame hasn't moved in the superview but the content inside the frame has changed because the origin of the bounds rectangle starts at a different part of the view. This is the whole idea behind a
UIScrollView
and it's subclasses (for example, aUITableView
). See Understanding UIScrollView for more explanation.When to use frame and when to use bounds
Since
frame
relates a view's location in its parent view, you use it when you are making outward changes, like changing its width or finding the distance between the view and the top of its parent view.Use the
bounds
when you are making inward changes, like drawing things or arranging subviews within the view. Also use the bounds to get the size of the view if you have done some transfomation on it.Articles for further research:
Apple docs
Related StackOverflow questions
Other resources
Practice yourself
In addition to reading the above articles, it helps me a lot to make a test app. You might want to try to do something similar. (I got the idea from this video course but unfortunately it isn't free.)
Here is the code for your reference:
The answers above have very well explained the difference between Bounds and Frames.
Then there is confusion that in case of Bounds the X,Y will always be "0". This is not true. This can be understood in UIScrollView and UICollectionView as well.
When bounds' x, y are not 0.
Let's assume we have a UIScrollView. We have implemented pagination. The UIScrollView has 3 pages and its ContentSize's width is three times Screen Width (assume ScreenWidth is 320). The height is constant (assume 200).
Add three UIImageViews as subViews and keep a close look at the x value of frame
Page 0: When the ScrollView is at 0 Page the Bounds will be (x:0,y:0, width : 320, height : 200)
Page 1: Scroll and move to Page 1.
Now the bounds will be (x:320,y:0, width : 320, height : 200) Remember we said with respect to its own coordinate System. So now the "Visible Part" of our ScrollView has its "x" at 320. Look at the frame of imageView1.
Same for the case of UICollectionView. The easiest way to look at collectionView is to scroll it and print/log its bounds and you will get the idea.
try to run the code below
the output of this code is:
case device orientation is Portrait
case device orientation is Landscape
obviously, you can see the difference between frame and bounds
frame is the origin (top left corner) and size of the view in its super view's coordinate system , this means that you translate the view in its super view by changing the frame origin , bounds on the other hand is the size and origin in its own coordinate system , so by default the bounds origin is (0,0).
most of the time the frame and bounds are congruent , but if you have a view of frame ((140,65),(200,250)) and bounds ((0,0),(200,250))for example and the view was tilted so that it stands on its bottom right corner , then the bounds will still be ((0,0),(200,250)) , but the frame is not .
the frame will be the smallest rectangle that encapsulates/surrounds the view , so the frame (as in the photo) will be ((140,65),(320,320)).
another difference is for example if you have a superView whose bounds is ((0,0),(200,200)) and this superView has a subView whose frame is ((20,20),(100,100)) and you changed the superView bounds to ((20,20),(200,200)) , then the subView frame will be still ((20,20),(100,100)) but offseted by (20,20) because its superview coordinate system was offseted by (20,20).
i hope this helps somebody.