UIView和它的子类都有frame和bounds属性。有什么不同?


当前回答

试着运行下面的代码

- (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相对于它的父视图。

bounds rect是定义NSView坐标系的值的范围。

也就是说,这个矩形中的任何东西都会显示在UIView中。

上面的答案已经很好地解释了边界和框架之间的区别。

边界:一个视图的大小和位置按照它自己的坐标系统。 Frame:相对于它的SuperView的视图大小和位置。

然后有一个混乱的情况下,边界的X,Y将永远是“0”。这是不对的。这也可以在UIScrollView和UICollectionView中理解。

当边界' x, y不为0时。 假设我们有一个UIScrollView。我们实现了分页。UIScrollView有3个页面,它的ContentSize的宽度是屏幕宽度的3倍(假设屏幕宽度是320)。高度是常数(假设200)。

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

添加三个UIImageViews作为子视图,并密切关注frame的x值

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)

0页: 当ScrollView为0时,Page的边界将为 (x:0,y:0,宽:320,高:200) 第1页: 滚动并移动到第1页。 现在边界将是(x:320,y:0,宽度:320,高度:200) 记住我们说过在它自己的坐标系中。现在我们ScrollView的可见部分的x值是320。看看imageView1的帧。 第2页: 滚动并移动到第2页 边界:(x:640,y:0,宽:320,高:200) 再看一下imageView2的帧

UICollectionView的情况也一样。查看collectionView最简单的方法是滚动它并打印/记录它的边界,您将了解它的概念。

Frame是视图在它的父视图坐标系中的原点(左上角)和大小,这意味着你在它的父视图中通过改变帧原点来转换视图,另一方面,边界是它自己坐标系中的大小和原点,所以默认情况下边界原点是(0,0)。

大多数情况下,框架和边界是相等的,但如果你有一个框架((140,65),(200,250))和边界((0,0),(200,250))的视图,并且视图倾斜到它的右下角,那么边界仍然是((0,0),(200,250)),但框架不是。

框架将是封装/包围视图的最小矩形,因此框架(如照片中的)将是((140,65),(320,320))。

另一个区别是,例如,如果你有一个边界为((0,0),(200,200)的superView,这个superView有一个框架为((20,20),(100,100)的子view,你把superView的边界改为((20,20),(200,200)),那么子view的框架仍然是((20,20),(100,100)),但是被(20,20)偏移,因为它的父视图坐标系被(20,20)偏移。

我希望这能帮助到一些人。

这里有一个很棒的视频(来自Sean Allen):

Swift - Bounds vs. Frame - iOS面试问题

框架是相对于父视图坐标的位置:

边界是相对于自身坐标系的位置。

和…如果视图是旋转的,它会变得更加棘手。(看视频!)

iOS框架与边界

frame and bounds有CGRect类型,这些属性你可以在UIView和CALayer中找到[关于]

Frame与边界、位置、变换有直接关系:

(x, y)依赖于parenView和 (宽度,高度)被边界占据的完整矩形。

范围:

(x, y) = 0,0 (width, height)是视图的宽度和高度

再举一个例子来说明框架和边界之间的区别。 在这个例子中:

视图B是视图a的子视图 视图B被移动到x:72, y: 22 视图B旋转了45度

let viewB = UIView(frame: CGRect(origin: CGPoint(x: 72, y: 22), size: CGSize(width: 20, height: 40)))
viewB.backgroundColor = .cyan
let radian = 45 * CGFloat.pi / 180
viewB.transform = CGAffineTransform(rotationAngle: radian)
viewA.addSubview(viewB)

[iOS像素、点数、单位]