iOS 中的 bounds & frame

由于種種原因,簡書等第三方平臺博客不再保證能夠同步更新,歡迎移步 GitHub:https://github.com/kingcos/Perspective/。謝謝!

bounds & frame

  • Info:
  • Swift 3.0
  • Xcode 8.2.1

Update

2017.02.27 - CS193p Lecture 04

  • 使用 frame & center 來定位視圖
  • 使用 bounds 來繪制視圖

frame.size != bounds.size

  • 在視圖旋轉(zhuǎn)時,frame 的 size 和 bounds 的 size 將發(fā)生分歧,即 frame 的 size 將相對于父視圖的坐標(biāo)系而改變。
  • 該示例已增加,詳見 kingcos/bounds-frame-Demo 新增的 Demo。

redraw

  • 默認(rèn)情況下,UIView 的 bounds 改變時,將不會重新繪制。
  • 設(shè)置 Content Mode 為 redraw 即會重新繪制。
  • UIViewContentMode: 內(nèi)容模式(僅放置在某個位置、比例縮放、重新繪制)

前言

在 iOS 開發(fā)中,視圖的 bounds 和 frame 是其最基本的屬性。兩者的類型均為 CGRect,即包含原點和寬高信息。那么這兩個屬性有什么區(qū)別和聯(lián)系呢?為了搞清楚這一點,也為了方便以后的參考,所以總結(jié)于此。

概念

frame

The frame rectangle, which describes the view’s location and size in its superview’s coordinate system.

根據(jù)蘋果的官方文檔,frame 是控件相對于其父視圖坐標(biāo)系得出的位置和大小。

center

其實提到 frame 和 bounds,不得不說的還有一個屬性便是 center。

The center of the frame.

根據(jù)蘋果的官方文檔,center 是自身控件 frame 的中心。

bounds

The bounds rectangle, which describes the view’s location and size in its own coordinate system.

根據(jù)蘋果的官方文檔,bounds 是控件相對于其自身坐標(biāo)系得出的位置和大小。默認(rèn) bounds 中的原點為 (0, 0)。

Demo

驗證

概念的總結(jié)總是抽象的,不如一個 Demo 生動,因此寫了一個 Demo 來驗證以上的概念。該 Demo 您可以在 kingcos/bounds-frame-Demo 下載并使用 Xcode 運行。為了快速構(gòu)建,該例中使用了 Storyboard。

Demo

該 Demo 中,紅色和藍(lán)色按鈕的父控件為 UIView,您可以在下圖中看到,即藍(lán)色選中的視圖控件。

控件層次

通過 Demo 中的數(shù)據(jù),我們可以很清楚的知道 frame、bounds 以及 center 之間的關(guān)系:

  • frame 和 bounds 中的 size 是相同且同時變化的
  • 當(dāng)子控件的左上角(即原點)與其父控件為同一點時,frame 和 bounds 是相同的
  • frame 中的原點為當(dāng)前控件在父控件中的坐標(biāo)
  • bounds 中的原點為當(dāng)前控件在其以自身為準(zhǔn)的坐標(biāo)系中的坐標(biāo),默認(rèn)為 (0, 0)
  • center 為 frame 的中心,即相對于父控件

應(yīng)用

驗證了概念,也大致了解了 frame 和 bounds 的區(qū)別,那么在實際應(yīng)用中又有什么差別呢?在 Demo 的基礎(chǔ)上,新增了下方的一個 UIView,背景色為 Light Gray(如控件層次圖中藍(lán)色選中的視圖)。并在該 UIView 中嵌套了一個子控件,即棕色的 UILabel。在該棕色 UILabel 中,又使用代碼創(chuàng)建了子控件 UIView,并將其初始化為 UIView(frame: CGRect(x: 0, y: 0, width: 20, height: 20)),且背景為黑色。

Demo
控件層次

為了方便演示,在棕色 UILabel 上方加上了一個 UISegmentedControl,用來快速切換設(shè)置的不同屬性,以方便比較。默認(rèn)即初始狀態(tài)為:黑色控件、棕色 Label、淺灰控件三者的原點統(tǒng)一。

Bounds

當(dāng)點選 Bounds,設(shè)置棕色 Label 的 bounds 原點:

brownLabel.bounds.origin = CGPoint(x: -20, y: -20)

雖然原點變化了,但是該控件的位置并沒有發(fā)生改變,這是因為 bounds 以自身為參照,僅僅把原點坐標(biāo)改變,不會影響自身。但是我們添加到該控件內(nèi)部的黑色控件,就會發(fā)生偏移。偏移的動畫如下圖所示:

改變 bounds

Frame

當(dāng)點選 Frame,設(shè)置棕色 Label 的 frame 原點:

brownLabel.frame.origin = CGPoint(x: -20, y: -20)

由于 frame 是參照父控件,所以一旦更改原點,那么棕色控件本身就會發(fā)生偏移。而其內(nèi)部的子控件是按照其父控件定位的,所以也會跟著偏移,但相對棕色控件的位置不變。

改變 frame

總結(jié)

bounds 和 frame 其實是 iOS 開發(fā)中很基本的知識點,但有時會對初學(xué)者造成困惑。背誦概念是很容易忘記的,通過實際的代碼和 Demo 才能對知識掌握更加清晰、牢靠。

參考資料

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容