iOS學(xué)習(xí)筆記(1)-iPhone分辨率和坐標(biāo)系

終于決定開始學(xué)習(xí)ios開發(fā)了,很久之前有過一次ios開發(fā)培訓(xùn),但是做完作業(yè)就落下了,一直沒有再撿起。想到如今ios開發(fā)如火如荼,再不學(xué)習(xí)真的要掉隊(duì)了,希望能督促自己在2個(gè)月內(nèi)完成ios開發(fā)的基礎(chǔ)學(xué)習(xí)以及寫出一個(gè)demo。這是第一篇,先總結(jié)下iphone的分辨率以及圖像基礎(chǔ)知識(shí),由于對(duì)圖形圖像的一些概念并不太熟,錯(cuò)誤在所難免,請(qǐng)大蝦指正。

1 Points/DPI & Pixels/PPI

在談到iPhone的分辨率之前,先要說(shuō)說(shuō)ios開發(fā)里面Points和Pixels的概念。在ios開發(fā)中,一個(gè)控件的坐標(biāo)尺寸都是用邏輯點(diǎn)Points來(lái)表示,Points是抽象單元,僅僅只是在坐標(biāo)空間起作用。我們實(shí)際看到的控件都是像素點(diǎn)Pixels。DPI(dot per inch)是每英寸(1英寸=2.54厘米)的邏輯點(diǎn)的個(gè)數(shù),比如iPhone5的邏輯分辨率320x568,DPI為163。為PPI(pixel per inch)則是每英寸的像素點(diǎn)的個(gè)數(shù),比如iPhone5的物理分辨率為640x1136,PPI為326,iPhone6 Plus的物理分辨率為1080 x 1092,PPI為401。個(gè)人理解的一點(diǎn)是,顯示內(nèi)容多少跟DPI相關(guān),也就是我們?cè)诖a里面設(shè)定的大小,而顯示的精細(xì)程度則跟PPI和素材本身的分辨率相關(guān)

Update: 另外要說(shuō)明的一點(diǎn)是,我們有時(shí)候看到一張圖片,大小為640X960,這個(gè)其實(shí)是水平和垂直方向的像素點(diǎn)數(shù)目,像素點(diǎn)多并不代表圖片就越大,還有個(gè)因素很重要,就是分辨率。對(duì)于兩張像素點(diǎn)一樣的圖片,比如都是640X960,其中一張圖片分辨率為144PPI,另一張圖片分辨率為72PPI,那么,分辨率為144的圖片會(huì)比72的小。

如下圖所示,ios應(yīng)用中,首先代碼中設(shè)定的Points首先會(huì)根據(jù)一定的scale factor縮放因子渲染為像素。比如iPhone4之前的縮放因子都是1,而iPhone4-iPhone6因?yàn)樘岣吡朔直媛剩虼丝s放因子增加為2,而iPhone6 Plus分辨率更高,縮放因子為3。對(duì)于同樣大小的圖片,在不同的分辨率顯示會(huì)有差異,在高分辨率的機(jī)器上會(huì)變小,為了保證在所有型號(hào)機(jī)器上看起來(lái)圖片大小一致,所以需要不同大小的圖片,這也是ios開發(fā)中的圖片資源會(huì)有1x,2x以及3x這三種的原因。圖后附有xcode代碼打印出的Points和Pixels的值,可以驗(yàn)證一下。

圖1 - The Ultimate Guide To iPhone Resolutions
####測(cè)試代碼
UIScreen *mainScreen = [UIScreen mainScreen];
NSLog(@"Screen bounds: %@, Screen resolution: %@, scale: %f, nativeScale: %f",
    NSStringFromCGRect(mainScreen.bounds),mainScreen.coordinateSpace,mainScreen.scale, 
          mainScreen.nativeScale);

####輸出
iPhone4s:
Screen bounds: {{0, 0}, {320, 480}}, Screen resolution: <UIScreen: 0x7ba30360; bounds = {{0, 0}, {320, 480}}; mode = <UIScreenMode: 0x7ba30650; size = 640.000000 x 960.000000>>, scale: 2.000000, nativeScale: 2.000000

iPhone5:
Screen bounds: {{0, 0}, {320, 568}}, Screen resolution: <UIScreen: 0x7b932140; bounds = {{0, 0}, {320, 568}}; mode = <UIScreenMode: 0x7b9301b0; size = 640.000000 x 1136.000000>>, scale: 2.000000, nativeScale: 2.000000

iPhone6:
Screen bounds: {{0, 0}, {375, 667}}, Screen resolution: <UIScreen: 0x7fd340c0f6f0; bounds = {{0, 0}, {375, 667}}; mode = <UIScreenMode: 0x7fd340c0fba0; size = 750.000000 x 1334.000000>>, scale: 2.000000, nativeScale: 2.000000

iPhone6 Plus:
Screen bounds: {{0, 0}, {414, 736}}, Screen resolution: <UIScreen: 0x7f924b40b1d0; bounds = {{0, 0}, {414, 736}}; mode = <UIScreenMode: 0x7f924b40b6d0; size = 1242.000000 x 2208.000000>>, scale: 3.000000, nativeScale: 3.000000

除了iPhone6 Plus外,經(jīng)過第一步的根據(jù)scale factor進(jìn)行縮放后的像素就是最終顯示的物理像素。由于iPhone6 Plus的屏幕分辨率為1080 x 1920, 而上一步縮放得到的分辨率為1242 × 2208,因此需要再經(jīng)過一次向下取樣(downsample)的過程,對(duì)于一張圖片來(lái)說(shuō),大小變成了之前的87%(1080/1242=20/23)左右,之前縮放的23個(gè)像素要映射到屏幕的20個(gè)像素上。我們?cè)陂_發(fā)的時(shí)候,3x的圖片的分辨率要調(diào)成1242 x 2208,由ios去完成向下取樣的過程。示例參見http://www.paintcodeapp.com/news/iphone-6-screens-demystified
,而向下取樣帶來(lái)的影響參見這篇文章的分析http://oleb.net/blog/2014/11/iphone-6-plus-screen/

2 再談iPhone6 Plus的分辨率設(shè)置

第一個(gè)疑問是為什么iPhone6 Plus的邏輯分辨率要用414*736呢,如果用360 x 640貌似也OK,放大三倍后正好是1080 x 1920,都可以省去后面那個(gè)downsample的步驟了。參考資料2詳細(xì)分析了iPhone6 Plus的邏輯分辨率這樣設(shè)置的原因,摘錄如下,先看圖:

圖2 - iPhone規(guī)格和分辨率
  • 如果邏輯分辨率用360 x 640,放大3x后確實(shí)正好跟屏幕分辨率一致,省去了doansample的步驟。但是這樣帶來(lái)的問題是6P的邏輯分辨率 360x640 比 iPhone 6的 375x667 還低,6P的大屏幕雖然很精細(xì),但是可顯示的實(shí)際內(nèi)容比6還少,太不科學(xué)。打個(gè)比方就是:相同字號(hào)的情況下,6如果一行顯示了25個(gè)字,而6P就會(huì)只能顯示24個(gè)字了。
  • 如果邏輯分辨率為540 x 960,放大2x就可以跟屏幕分辨率一致,這樣也就不用3x的圖片了。但是這樣帶來(lái)的問題是6P的邏輯分辨率差不多是6的兩倍,確實(shí)可以顯示更多的內(nèi)容了,但是UI控件可以顯示的實(shí)際物理面積變小了,標(biāo)簽欄或?qū)Ш綑诎粹o的物理高度只有原來(lái)的81.5%(163/200),點(diǎn)擊面積只有原來(lái)的66.4%(81.5% x 81.5%),這樣點(diǎn)擊就更加困難了。
  • 因此最好的方案應(yīng)該是圖中的iPhone6 Plus(a)了,物理像素1242 x 2208,在5.5英寸的屏幕上這個(gè)ppi就要達(dá)到461了,而蘋果最終并沒有采用這個(gè)方案,而是縮放到了1080 x 1920。可能的原因是如果分辨率達(dá)到461ppi,則內(nèi)存消耗增大,電池消耗增大,工藝上可能也有難度。當(dāng)然如果后續(xù)技術(shù)提高后,克服了這些困難,則很可能不用downsample了。
  • 如果我們不用3x的圖片,而是將2x的圖片用在6P中,則會(huì)出現(xiàn)明顯的鋸齒或模糊。

3 ios開發(fā)中的坐標(biāo)系

ios開發(fā)中坐標(biāo)系至關(guān)重要,直接關(guān)系UI控件最終的位置關(guān)系。其中有三個(gè)屬性要重點(diǎn)關(guān)注:bounds,center和frame,斯坦福大學(xué)的ios開發(fā)教程中有很精辟的注解,下面是這幾個(gè)屬性的定義:

@property CGRect bounds; // your view’s internal drawing space’s origin and size
// The bounds property is what you use inside your view’s own implementation.
// It is up to your implementation as to how to interpret the meaning of bounds.origin.

@property CGPoint center; // the center of your view in your superview’s coordinate space 

@property CGRect frame; // a rectangle in your superview’s coordinate space which entirely contains your view’s bounds.size

概括起來(lái)就是:

  • 坐標(biāo)系從左上角開始。
  • 坐標(biāo)系以Points為單元(注意,是邏輯點(diǎn)Points,不是像素Pixels)。最終ios會(huì)將UI控件自動(dòng)適配高分辨率,只要有相應(yīng)的2x和3x的素材提供。
  • bounds指的是視圖自己的范圍區(qū)域。
  • center指的是視圖的中心點(diǎn)在superview的坐標(biāo)系的坐標(biāo)。
  • frame則是視圖的superview坐標(biāo)系中包裹了這個(gè)UIView的矩形區(qū)域。
  • frame和bounds可能是相同的,但是不一定都相同,如果UIView本身旋轉(zhuǎn)了,則不會(huì)相同,具體見后面的圖示例。

下面這個(gè)圖詳細(xì)說(shuō)明了這幾個(gè)屬性的含義。

圖3 - iOS坐標(biāo)系

簡(jiǎn)單測(cè)試

測(cè)試代碼如下,在當(dāng)前UIView中加入一個(gè)UILabel,打印這個(gè)label的bounds,center以及frame,當(dāng)然這里沒有旋轉(zhuǎn)該UIView。可以看到label的center為{45, 35},正好是label在superview坐標(biāo)系中的坐標(biāo)。而label的bounds是針對(duì)自身那個(gè)矩形的,所以為{{0,0},{50,30}}。label的frame則是包裹它的矩形在superview坐標(biāo)系中的坐標(biāo),也就是{{20,20},{50, 30}}.

###測(cè)試代碼###
  CGRect labelRect = CGRectMake(20, 20, 50, 30);
  UILabel *label = [[UILabel alloc] initWithFrame:labelRect];
  label.text = @"Hello!";
  [self.view addSubview:label]; 
  NSLog(@"center:%@, bounds:%@, frame:%@", NSStringFromCGPoint(self.view.center), NSStringFromCGRect(self.view.bounds),
          NSStringFromCGRect(self.view.frame));
  NSLog(@"center:%@, bounds:%@, frame:%@", NSStringFromCGPoint(label.center), NSStringFromCGRect(label.bounds),
          NSStringFromCGRect(label.frame));
          
###輸出結(jié)果如下(模擬器為iPhone5s)###
2016-01-11 23:19:59.927 resolution[10719:2940751] center:{160, 284}, bounds:{{0, 0}, {320, 568}}, frame:{{0, 0}, {320, 568}}
2016-01-11 23:19:59.927 resolution[10719:2940751] center:{45, 35}, bounds:{{0, 0}, {50, 30}}, frame:{{20, 20}, {50, 30}}

4 參考資料

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,786評(píng)論 6 534
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,656評(píng)論 3 419
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,697評(píng)論 0 379
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,098評(píng)論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,855評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,254評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,322評(píng)論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,473評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,014評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,833評(píng)論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,016評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,568評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,273評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,680評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,946評(píng)論 1 288
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,730評(píng)論 3 393
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,006評(píng)論 2 374

推薦閱讀更多精彩內(nèi)容