iOS之頁(yè)面布局

原文請(qǐng)點(diǎn)擊

在《iOS 7 UI Transition Guide》中有在《iOS 7 UI Transition Guide》的Bar and Bar Buttons一節(jié)中有這么一段話

In iOS 7, the status bar is transparent, and other bars—that is, navigation bars, tab bars, toolbars, search bars, and scope bars—are translucent. As a general rule, you want to make sure that content fills the area behind the bars in your app.

翻譯過來:

在iOS7中娇昙,狀態(tài)欄是完全透明的冒掌,而其他bar蹲盘,即navigation bars, tab bars, toolbars, search bars和scope bars都是半透明的。開發(fā)者需要保證頁(yè)面內(nèi)容能覆蓋到這些bar的后面铃诬。

事實(shí)上苍凛,iOS7中的狀態(tài)欄不僅變完全透明了,而且完全不占空間宣肚。
有碼有真相 —— 新建一個(gè)UIViewController悠栓,再viewDidLoad里面輸入以下代碼按价,作為rootViewController啟動(dòng)應(yīng)用:

- (void)viewDidLoad
{  
    [super  viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    UILabel *label = [[[UILabel alloc]initWithFrame:CGRectMake(0, 0, 200, 20)]autorelease];
    label.text = @"I am a label";
    [self.view addSubview:label];
}

應(yīng)用效果:

Paste_Image.png

可以看到的是label和status bar悲催地重疊了楼镐。
我們?cè)偬滓粋€(gè)UINavigationController逮走,可以看到更悲催的事情:

Paste_Image.png

label活生生地被navigationBar蓋住了。

可以說茅信,蘋果這次在iOS7上的redesign對(duì)開發(fā)者來說是慘絕人寰的墓臭。
不過蘋果還是有節(jié)操的,在iOS7上運(yùn)行iOS7 SDK以下開發(fā)的應(yīng)用時(shí)酌摇,保留了原先的頁(yè)面結(jié)構(gòu)布局嗡载,并且做了不少向下兼容策略。
而且埂息,iOS7 SDK提供了一系列接口和策略方案遥巴,下文將會(huì)一一介紹并順帶剖析一下iOS7上的頁(yè)面結(jié)構(gòu)框架。

Realtime Debug Protal
首先介紹一個(gè)小工具拾弃,可以方便我們進(jìn)行學(xué)習(xí)摆霉。它的小名叫RDP,是一個(gè)類似Web Inspector的工具搭盾,把這個(gè)工具引入我們的項(xiàng)目工程刻两,并做一些簡(jiǎn)單的配置滴某,然后運(yùn)行真機(jī)或者模擬器。應(yīng)用啟動(dòng)后户誓,在瀏覽器輸入手機(jī)的IP地址,就可以看到UIView的樹狀結(jié)構(gòu)和Log信息碍彭,還可以在瀏覽器中對(duì)View進(jìn)行移動(dòng)悼潭,隱藏,選中高亮等操作皆疹。

Paste_Image.png

狀態(tài)欄
在iOS7中占拍,狀態(tài)欄是透明的晃酒,就是說,狀態(tài)欄只有文字沒有背景贝次。
而變透明之后就很容易和后面的內(nèi)容混淆浊闪,雖說一般應(yīng)用不會(huì)把內(nèi)容和狀態(tài)欄疊合在一起,但是至少搁宾,現(xiàn)在的情況是盖腿,默認(rèn)是會(huì)疊合的,開發(fā)需要從20px像素以下開始布局頁(yè)面元素才能避免翩腐。

蘋果為了讓深色淺色背景均能讓狀態(tài)欄內(nèi)容清晰顯示茂卦,提供兩種狀態(tài)欄樣式:

UIStatusBarStyleDefault = 0 黑色文字,淺色背景時(shí)使用
UIStatusBarStyleLightContent = 1 白色文字等龙,深色背景時(shí)使用

而以下兩個(gè)舊狀態(tài)欄樣式將被廢棄:
UIStatusBarStyleBlackTranslucent = 1
UIStatusBarStyleLightContent = 2

還有,iOS7中我們通過ViewController重載方法返回枚舉值的方法來控制狀態(tài)欄的隱藏和樣式罐栈。
首先,需要在Info.plist配置文件中琅翻,增加鍵:UIViewControllerBasedStatusBarAppearance柑贞,并設(shè)置為YES钧嘶;
然后,在UIViewController子類中實(shí)現(xiàn)以下兩個(gè)方法:

- (UIStatusBarStyle)preferredStatusBarStyle
{    
    return UIStatusBarStyleLightContent;
}

- (BOOL)prefersStatusBarHidden
{
    return NO;
}

最后摄欲,在需要刷新狀態(tài)欄樣式的時(shí)候疮薇,調(diào)用[self setNeedsStatusBarAppearanceUpdate]方法即可刷新,若果需要以動(dòng)畫形式切換狀態(tài)欄樣式按咒,則用以下方式調(diào)用即可:

[UIView animateWithDuration:0. animations:^{
    [self setNeedsStatusBarAppearanceUpdate];
}];

導(dǎo)航欄
在iOS7励七,由于狀態(tài)欄背景透明,那么吼野,導(dǎo)航欄背景就可能要兼職充當(dāng)狀態(tài)欄背景了两波。
iOS7默認(rèn)導(dǎo)航欄樣式就是這么做的单起,見下圖:

Paste_Image.png

雖然用戶看來劣坊,iOS7默認(rèn)樣式的狀態(tài)欄和導(dǎo)航欄時(shí)連在一起的,但是實(shí)際上導(dǎo)航欄的位置和大小是和之前系統(tǒng)版本一樣的测蘑,依然是貼在狀態(tài)欄下面, 依然是高44px;之所以用戶看來它們是連在一起固逗,這是因?yàn)閁INavigationBar里面的_UINavigationBarBackground 定位在y方向-20px的位置藕帜,然后高度增加到64px,這樣就可以同時(shí)充當(dāng)了兩者的背景贝攒。

關(guān)于這些定位时甚,蘋果做了很多工作,后面也會(huì)談到不少梨熙。不關(guān)心的同學(xué)可以略過刀诬,其實(shí)這些細(xì)節(jié),個(gè)人覺得质欲,即使對(duì)于開發(fā)者來說糠馆,也不是必需知道的,我們只需要知道怎么調(diào)用相關(guān)API就足夠了奋早。
實(shí)際情況下赠橙,我們會(huì)自定義導(dǎo)航欄背景,過去掉奄,我們也許會(huì)使用如下代碼把一張高44像素(retina/88像素)的圖片來平鋪?zhàn)鳛閷?dǎo)航欄背景。

[navCtrl.navigationBar setBackgroundImage:[UIImage imageNamed:@"nav_background"] forBarMetrics:UIBarMetricsDefault];

啟動(dòng)應(yīng)用诞仓,出現(xiàn)了意想不到的效果和久違的界面 —— 黑底白字的狀態(tài)欄速兔,不再被navigationBar蓋住的label。

Paste_Image.png

這里兩個(gè)點(diǎn)需要解釋一下:

  1. 若我們使用自定義圖片作為導(dǎo)航欄的背景谍婉,那么UIViewController的view(下面稱為視圖)就不會(huì)延伸到navigationBar的頂部镀钓,而是從它的底部開始——正如往常一樣。
  2. 若我們使用一張高44像素(retina/88像素)的圖片作為導(dǎo)航欄背景丁溅,那么狀態(tài)欄就會(huì)保持黑色,圖片只會(huì)在導(dǎo)航欄區(qū)域平鋪妓柜。

另外涯穷,iOS7 SDK中新增了一個(gè)設(shè)置背景圖片的方法(setBackgroundImage:forBarPosition:barMetrics:)求豫,比原有的方法多了一個(gè)UIBarPosition枚舉參數(shù),用于設(shè)置背景圖片拉伸的策略最疆。
針對(duì)不同的拉伸設(shè)置和背景圖片尺寸蚤告,在《iOS 7 UI Transition Guide》的Bar and Bar Buttons一節(jié)中
中有詳細(xì)說明:

Paste_Image.png

頁(yè)面布局
在 《iOS 7 UI Transition Guide》的Layout and Appearance 一節(jié)中也提到 —— 在iOS7中杜恰,view controllers使用全屏布局 (In iOS 7, view controllers use full-screen layout)。

通過上面的討論我們也知道心褐,除非導(dǎo)航欄設(shè)置了自定義的背景圖片逗爹,否則每個(gè)視圖都會(huì)延伸到屏幕一樣大小的。
所以,像上面第二張圖片中出現(xiàn)導(dǎo)航欄遮蓋label的情況也是正常的現(xiàn)象于购。

如果我們要讓label從導(dǎo)航欄以下位置顯示知染,可以通過修改UIViewController的edgesForExtendedLayout這個(gè)屬性來實(shí)現(xiàn)控淡。
edgesForExtendedLayout是一個(gè)類型為UIExtendedEdge的屬性,指定邊緣要延伸的方向逸寓。
因?yàn)閕OS7鼓勵(lì)全屏布局竹伸,它的默認(rèn)值很自然地是UIRectEdgeAll簇宽,四周邊緣均延伸,就是說譬嚣,如果即使視圖中上有navigationBar钞它,下有tabBar,那么視圖仍會(huì)延伸覆蓋到四周的區(qū)域尼桶。

如果把視圖做如下設(shè)置锯仪,那么視圖就不會(huì)延伸到這些bar的后面了,于是label又出來了小腊。

self.edgesForExtendedLayout = UIExtendedEdgeNone;
Paste_Image.png

也許秩冈,這時(shí)候你會(huì)想斥扛,那為什么不把UIExtendedEdgeNone作為默認(rèn)態(tài)呢?
iOS7以后鼓勵(lì)全屏队他,它希望用戶在使用可滾動(dòng)視圖的時(shí)候可以透過半透明的bar還可以看到一些模模糊糊的內(nèi)容。

為了保持設(shè)計(jì)的優(yōu)雅锡凝,同時(shí)避免給開發(fā)者太多的困擾垢啼,iOS7在Conttoller中新增了這個(gè)屬性:automaticallyAdjustsScrollViewInsets,當(dāng)設(shè)置為YES時(shí)(默認(rèn)YES)锚扎,如果視圖里面存在唯一一個(gè)UIScrollView或其子類View馁启,那么它會(huì)自動(dòng)設(shè)置相應(yīng)的內(nèi)邊距,這樣可以讓scroll占據(jù)整個(gè)視圖翠勉,又不會(huì)讓導(dǎo)航欄遮蓋霉颠,如以下例子:

Paste_Image.png

要注意的是蒿偎,這個(gè)例子中我們沒有設(shè)置edgesForExtendedLayout,即視圖是延伸至全屏的华坦。
我們可以從UIView樹狀圖看到不从,tableview的bounds值中有64像素的偏移值,它作為一個(gè)內(nèi)邊距來保持內(nèi)容顯示在導(dǎo)航欄以下歹袁,而滾動(dòng)時(shí)仍可以透過半透明的導(dǎo)航欄看到模糊的內(nèi)容寝优。

最后一個(gè)介紹的新屬性是extendedLayoutIncludesOpaqueBars,這個(gè)屬性指定了當(dāng)Bar使用了不透明圖片時(shí)孟抗,視圖是否延伸至Bar所在區(qū)域,默認(rèn)值時(shí)NO铅协。
所以我們?nèi)绻远x了導(dǎo)航欄的背景圖片摊沉,那么視圖會(huì)從導(dǎo)航欄以下開始说墨,不會(huì)延伸到導(dǎo)航欄區(qū)域。
如果把這個(gè)屬性設(shè)置為YES尼斧,那么視圖將會(huì)延伸至導(dǎo)航欄區(qū)域棺棵,即使我們把導(dǎo)航欄設(shè)置成了自定義背景楼咳,如下圖:

Paste_Image.png

視圖延伸之后,label又被導(dǎo)航欄覆蓋住了律秃,正如我們意料爬橡。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末治唤,一起剝皮案震驚了整個(gè)濱河市棒动,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌宾添,老刑警劉巖船惨,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異缕陕,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)扛邑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門怜浅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蔬崩,你說我怎么就攤上這事恶座。” “怎么了沥阳?”我有些...
    開封第一講書人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵跨琳,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我桐罕,道長(zhǎng)脉让,這世上最難降的妖魔是什么桂敛? 我笑而不...
    開封第一講書人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮溅潜,結(jié)果婚禮上术唬,老公的妹妹穿的比我還像新娘。我一直安慰自己伟恶,他們只是感情好碴开,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著博秫,像睡著了一般潦牛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上挡育,一...
    開封第一講書人閱讀 51,488評(píng)論 1 302
  • 那天巴碗,我揣著相機(jī)與錄音,去河邊找鬼即寒。 笑死橡淆,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的母赵。 我是一名探鬼主播逸爵,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼凹嘲!你這毒婦竟也來了师倔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤周蹭,失蹤者是張志新(化名)和其女友劉穎趋艘,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凶朗,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瓷胧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了棚愤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片搓萧。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖宛畦,靈堂內(nèi)的尸體忽然破棺而出瘸洛,到底是詐尸還是另有隱情,我是刑警寧澤刃永,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布货矮,位于F島的核電站,受9級(jí)特大地震影響斯够,放射性物質(zhì)發(fā)生泄漏囚玫。R本人自食惡果不足惜喧锦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望抓督。 院中可真熱鬧燃少,春花似錦、人聲如沸铃在。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)定铜。三九已至阳液,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間揣炕,已是汗流浹背帘皿。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留畸陡,地道東北人鹰溜。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像丁恭,于是被迫代替她去往敵國(guó)和親曹动。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

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