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)如圖:
可以發(fā)現(xiàn)label與導(dǎo)航欄發(fā)生了重疊,由此可以推知:
iOS7后,坐標(biāo)(0, 0)從整個(gè)屏幕的左上頂點(diǎn)開(kāi)始計(jì)算。
當(dāng)我們?cè)谠揢IViewController外套一個(gè)UINavigationController后顯示如圖:
整個(gè)label被UINavigationBar覆蓋了。
利用檢測(cè)任意view的subviews的關(guān)系樹(shù)一文中提供的工具方法打印keyWIndow的subViews樹(shù):如圖
由上圖可以知曉:
UINavigationBar的高度依舊是44px,
其子View: UINavigationBarBackground高度為64px,origin.y=-20,
所以UINavigationBarBackground充當(dāng)了狀態(tài)欄和導(dǎo)航欄的背景。這也解釋了通過(guò)修改UINavigationBar背景來(lái)改變導(dǎo)航欄背景的原理。
我們?yōu)閁INavigationBar添加背景圖片:如圖
此時(shí)打印視圖樹(shù),如圖:
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)航欄后面了
可以發(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ù)如圖:
分析:
以上代碼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,其效果和子視圖如圖:
分析:代碼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
效果如圖:
2,將圖片換成barbar66@2x.png:160*66
效果如圖:
3,將圖片換成barbar100@2x.png:182*100
效果如圖:
4,將圖片換成barbar100@2x.png:182*128
效果如圖:
5,將圖片換成barbar228@2x.png:415*228
效果如圖:
有以上結(jié)果可見(jiàn):
假設(shè)圖片高度為h,
- 當(dāng)h<88 或者 88<h<128時(shí),縱向橫向平鋪,覆蓋導(dǎo)航欄
- 當(dāng)h=88時(shí),橫向平鋪,不覆蓋導(dǎo)航欄
- 當(dāng)h=128時(shí),橫向平鋪,覆蓋導(dǎo)航欄
- 當(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ò)誤歡迎指正留言。