iOS導(dǎo)航欄

iOS7之后UI發(fā)生大變化。apple鼓勵(lì)開(kāi)發(fā)者進(jìn)行全屏設(shè)計(jì),這些并在UI的一些特性上也有所表現(xiàn)。

1.屏幕坐標(biāo)起始點(diǎn)的變化
新建一個(gè)UIViewController并作為項(xiàng)目的RootController,在其View頂部添加一個(gè)UILabel,frame=(0,0,200,20)如圖:

bar01.png

可以發(fā)現(xiàn)label與導(dǎo)航欄發(fā)生了重疊,由此可以推知:

iOS7后,坐標(biāo)(0, 0)從整個(gè)屏幕的左上頂點(diǎn)開(kāi)始計(jì)算。

當(dāng)我們?cè)谠揢IViewController外套一個(gè)UINavigationController后顯示如圖:


bar02.png

整個(gè)label被UINavigationBar覆蓋了。

利用檢測(cè)任意view的subviews的關(guān)系樹(shù)一文中提供的工具方法打印keyWIndow的subViews樹(shù):如圖

bar03.png

由上圖可以知曉:

UINavigationBar的高度依舊是44px,
 其子View: UINavigationBarBackground高度為64px,origin.y=-20,
所以UINavigationBarBackground充當(dāng)了狀態(tài)欄和導(dǎo)航欄的背景。這也解釋了通過(guò)修改UINavigationBar背景來(lái)改變導(dǎo)航欄背景的原理。

我們?yōu)閁INavigationBar添加背景圖片:如圖

bar04.png

此時(shí)打印視圖樹(shù),如圖:

bar05.png

label視圖出現(xiàn)在了導(dǎo)航欄下方,該效果由UIViewController的一個(gè)屬性決定的:extendedLayoutIncludesOpaqueBars,這個(gè)屬性指定了當(dāng)Bar使用了不透明圖片時(shí),視圖是否延伸至Bar所在區(qū)域,默認(rèn)值時(shí)NO。如果把這個(gè)屬性設(shè)置為YES,那么視圖將會(huì)延伸至導(dǎo)航欄區(qū)域,即使我們把導(dǎo)航欄設(shè)置成了自定義背景。

1, 通過(guò)修改UINavigationBar的背景可以來(lái)修改狀態(tài)欄背景
2, 當(dāng)UIViewController. extendedLayoutIncludesOpaqueBars = NO 時(shí),UINavigationBar添加背景圖片后,UIViewController的視圖的原點(diǎn)坐標(biāo)為(0, 64), 下移了64px,并且高度縮減了64px。

通過(guò)設(shè)置UIViewController的屬性:edgesForExtendedLayout來(lái)使label出現(xiàn)在導(dǎo)航欄下方:

self.edgesForExtendedLayout = UIExtendedEdgeNone;

如圖:視圖不會(huì)再延伸到導(dǎo)航欄后面了

bar06.png
bar07.png

可以發(fā)現(xiàn)界面的變化,由此得出:

與為UINavigationBar添加背景圖片效果相同
當(dāng)視圖中存在UIScrollView時(shí)

1,存在唯一一個(gè)UIScrollView或者其子類(lèi)時(shí):<注意唯一一個(gè)>

  • ScrollView為添加的第一個(gè)子視圖
    代碼:
override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.whiteColor()

         /*****添加頂部UITableView*****/
        let table = UITableView.init(frame: self.view.bounds, style: .Plain);
        table.delegate = self;
        table.dataSource = self;
        self.view .addSubview(table)
        
        self.automaticallyAdjustsScrollViewInsets = true;
  
        /*****添加頂部UILabel*****/
        let label = UILabel.init(frame: CGRectMake(0, 0, 200, 20))
        label.text = "I am a label";
        self.view .addSubview(label)
    }

效果和視圖樹(shù)如圖:

bar08.png

bar09.png

分析:
以上代碼self.automaticallyAdjustsScrollViewInsets = true;,其中屬性automaticallyAdjustsScrollViewInsets默認(rèn)為true; 當(dāng)其值為true時(shí),如果視圖里面存在唯一一個(gè)UIScrollView或其子類(lèi)View,那么它會(huì)自動(dòng)設(shè)置相應(yīng)的內(nèi)邊距,但是不會(huì)重置scrollView的frame,這樣可以讓scroll占據(jù)整個(gè)視圖,又不會(huì)讓導(dǎo)航欄遮蓋。

  • ScrollView不是添加的第一個(gè)子視圖或者不止一個(gè)ScrollView
    代碼:
 override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.whiteColor()
        
        /*****添加頂部UILabel*****/
        let label = UILabel.init(frame: CGRectMake(0, 0, 200, 20))
        label.text = "I am a label";
        self.view .addSubview(label)
        
         /*****添加頂部Table*****/
        let table = UITableView.init(frame: self.view.bounds, style: .Plain);
        table.delegate = self;
        table.dataSource = self;
        self.view .addSubview(table)
        
        self.automaticallyAdjustsScrollViewInsets = true;
    }

本次是先添加label然后添加ScrollView,其效果和子視圖如圖:

bar11.png
bar10.png

分析:代碼self.automaticallyAdjustsScrollViewInsets = true;失效了。

此時(shí)我門(mén)可以使用屬性:self.edgesForExtendedLayout = UIExtendedEdgeNone;,然后將ScrollView的高相應(yīng)的縮減64px,來(lái)達(dá)到目的。

總結(jié)

iOS7之后apple鼓勵(lì)開(kāi)發(fā)者使用全屏布局,這樣導(dǎo)致了視圖的原點(diǎn)(0,0)為屏幕左上頂點(diǎn),而不再是狀態(tài)欄左下位置開(kāi)始。

UIViewController的屬性:

extendedLayoutIncludesOpaqueBars, 默認(rèn)為false,
說(shuō)明:這個(gè)屬性指定了當(dāng)Bar使用了不透明圖片時(shí),視圖是否延伸至Bar所在區(qū)域,默認(rèn)值時(shí)false。
所以我們?nèi)绻远x了導(dǎo)航欄的背景圖片,那么視圖會(huì)從導(dǎo)航欄以下開(kāi)始,不會(huì)延伸到導(dǎo)航欄區(qū)域。
如果把這個(gè)屬性設(shè)置為true,那么視圖將會(huì)延伸至導(dǎo)航欄區(qū)域,即使我們把導(dǎo)航欄設(shè)置成了自定義背景

edgesForExtendedLayout, 默認(rèn)為UIExtendedEdgeNone,
說(shuō)明: 這個(gè)屬性指定邊緣要延伸的方向。
因?yàn)閕OS7鼓勵(lì)全屏布局,它的默認(rèn)值很自然地是UIRectEdgeAll,四周邊緣均延伸,就是說(shuō),如果即使視圖中上有navigationBar,下有tabBar,那么視圖仍會(huì)延伸覆蓋到四周的區(qū)域。

automaticallyAdjustsScrollViewInsets, 默認(rèn)為true
當(dāng)設(shè)置為YES時(shí)(默認(rèn)YES),如果視圖里面存在唯一一個(gè)且為第一個(gè)加入視圖的UIScrollView或其子類(lèi)View,那么它會(huì)自動(dòng)設(shè)置相應(yīng)的內(nèi)邊距,這樣可以讓scroll占據(jù)整個(gè)視圖,又不會(huì)讓導(dǎo)航欄遮蓋。若ScrollView不止一個(gè)或者不是第一個(gè)加入子視圖則該屬性將失效。

導(dǎo)航欄圖片背景

添加背景圖片

 self.navigationController?.navigationBar .setBackgroundImage(UIImage.init(imageLiteral: "barbar66.png"), forBarPosition: UIBarPosition.Top, barMetrics: UIBarMetrics.Default)

1,作為導(dǎo)航背景的圖片:該圖片是一個(gè)@2x圖片:160*88

barbar88@2x.png

效果如圖:

bar12.png

2,將圖片換成barbar66@2x.png:160*66
效果如圖:

bar13.png

3,將圖片換成barbar100@2x.png:182*100
效果如圖:

bar14.png

4,將圖片換成barbar100@2x.png:182*128
效果如圖:

bar15.png

5,將圖片換成barbar228@2x.png:415*228
效果如圖:

bar16.png

有以上結(jié)果可見(jiàn):
假設(shè)圖片高度為h,

  1. 當(dāng)h<88 或者 88<h<128時(shí),縱向橫向平鋪,覆蓋導(dǎo)航欄
  2. 當(dāng)h=88時(shí),橫向平鋪,不覆蓋導(dǎo)航欄
  3. 當(dāng)h=128時(shí),橫向平鋪,覆蓋導(dǎo)航欄
  4. 當(dāng)h>128時(shí),縱向截取,橫向平鋪,覆蓋導(dǎo)航欄

得到以上結(jié)論的前提是:所有圖片是@2x圖。關(guān)于一倍圖,無(wú)論何種情況都是橫向平鋪縱向拉伸。

有關(guān)參數(shù):BarPosition和barMetrics的確切作用目前還不十分清楚,等弄清楚了后續(xù)補(bǔ)充。

附上UINavigationBar的擴(kuò)展,內(nèi)涵:bar去下邊線(xiàn),bar透明,bar恢復(fù)默認(rèn)狀態(tài)等。見(jiàn)地址:http://pan.baidu.com/s/1i4UqdFJ

以上內(nèi)容如有不足或錯(cuò)誤歡迎指正留言。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 參考文章 navigationItem UINavigationItem UINavigationBar UIBa...
    劉大帥閱讀 52,722評(píng)論 37 147
  • 一點(diǎn)說(shuō)明:本文中“導(dǎo)航控制器”區(qū)別于“視圖控制器”存在 UINavigationController UINavi...
    WeiHing閱讀 5,080評(píng)論 0 11
  • 最近項(xiàng)目里有個(gè)需求和導(dǎo)航欄的樣式定制有關(guān),深入之后發(fā)現(xiàn)之前理解的一些概念有些模糊,剛好趁著這次機(jī)會(huì)全面整理了一下。...
    Kevin追夢(mèng)先生閱讀 521評(píng)論 0 0
  • 最近項(xiàng)目里有個(gè)需求和導(dǎo)航欄的樣式定制有關(guān),深入之后發(fā)現(xiàn)之前理解的一些概念有些模糊,剛好趁著這次機(jī)會(huì)全面整理了一下。...
    hi_xgb閱讀 5,113評(píng)論 4 39
  • 這個(gè)時(shí)代不缺聰明的人,用心的人卻不多。 真正的勤奮來(lái)自于一個(gè)人的內(nèi)心深處,對(duì)于那些無(wú)法獲得即刻回報(bào)的事情,依然能夠...
    筱南愛(ài)吃肥肉閱讀 189評(píng)論 0 1