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


当前回答

这里有一个很棒的视频(来自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像素、点数、单位]

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

边界:一个视图的大小和位置按照它自己的坐标系统。 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最简单的方法是滚动它并打印/记录它的边界,您将了解它的概念。

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

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

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

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

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

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)偏移。

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

框架与边界

If you create a view at X:0, Y:0, width:400, height:400, its frame and bounds are the same. If you move that view to X:400, its frame will reflect that change but its bounds will not. Remember, the bounds is relative to the view’s own space, and internally to the view nothing has changed. If you transform the view, e.g. rotating it or scaling it up, the frame will change to reflect that, but the bounds still won’t – as far as the view is concerned internally, it hasn’t changed. If you change the bounds then it will change the content inside the frame because the origin of the bounds rectangle starts at a different part of the view.