translucent
先來看下官方文檔
/*
New behavior on iOS 7.
Default is YES.
You may force an opaque background by setting the property to NO.
If the navigation bar has a custom background image, the default is inferred
from the alpha values of the image—YES if it has any pixel with alpha < 1.0
If you send setTranslucent:YES to a bar with an opaque custom background image
it will apply a system opacity less than 1.0 to the image.
If you send setTranslucent:NO to a bar with a translucent custom background image
it will provide an opaque background for the image using the bar's barTintColor if defined, or black
for UIBarStyleBlack or white for UIBarStyleDefault if barTintColor is nil.
*/
@property(nonatomic,assign,getter=isTranslucent) BOOL translucent API_AVAILABLE(ios(3.0)) UI_APPEARANCE_SELECTOR; // Default is NO on iOS 6 and earlier. Always YES if barStyle is set to UIBarStyleBlackTranslucent
iOS 7 之后,該屬性默認為 YES
。但是如果給導航欄設置了一張自定義的背景圖片,如果該圖片有一個 alpha<1
的像素,那么該值就為 YES
,否則為 NO
。(設置導航欄的背景圖片會影響 translucent
的默認值)
如果手動設置了該屬性,并且設置了導航欄的背景圖,則系統(tǒng)可能會對背景圖進行處理:
- 如果設置該屬性為
YES
,但是提供了一張不透明的背景圖,系統(tǒng)會對該背景圖進行半透明處理
- 如果設置該屬性為
- 如果設置該屬性為
NO
,但是提供了一張半透明的背景圖,則系統(tǒng)會對該背景圖進行不透明處理。具體是根據(jù)導航欄的style
或者barTintColor
進行處理
- 如果設置該屬性為
總結(iOS 7 以上系統(tǒng)):
- 當導航欄沒有被隱藏時,且
translucent
屬性設置為YES
,那么,UIViewController
的view
的frame
起始點是從屏幕的左上角(0,0)開始,大小是整個屏幕寬高。而當translucent
屬性設置為NO
時,那么UIViewController
的view
的frame
起始點是從導航欄左下角開始,寬是屏幕的寬,高是整個屏幕減去導航欄的高度。
- 當導航欄沒有被隱藏時,且
-
UIViewController
的view
的子視圖布局推薦在viewWillLayoutSubviews
中進行,因為此時不管translucent
為何值,它的size
都是正確的。
-
示例
同樣一份代碼,在不同的控制器中,一個控制器導航欄是透明的,一個不透明
UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(30, 10, 200, 100)];
view1.backgroundColor = [UIColor redColor];
[self.view addSubview:view1];
UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(30, [UIScreen mainScreen].bounds.size.height - 200, 200, 200)];
view2.backgroundColor = [UIColor greenColor];
[self.view addSubview:view2];
運行截圖如下
push 時控件下移
push
操作是導航欄特有的,關于它的 translucent
上面也介紹了,下面從兩個方法分析
extendedLayoutIncludesOpaqueBars
官方文檔說明
@property(nonatomic,assign) BOOL extendedLayoutIncludesOpaqueBars API_AVAILABLE(ios(7.0)); // Defaults to NO, but bars are translucent by default on 7_0.
YES
代表當導航欄不透明時,當前頁面 view
的布局從導航欄頂部開始計算。 需要注意:導航欄半透明時,view
是包含導航欄的。如果一個導航欄不透明,另一個導航欄透明,切換就會出現(xiàn)問題。
edgesForExtendedLayout
官方文檔說明
typedef NS_OPTIONS(NSUInteger, UIRectEdge) {
UIRectEdgeNone = 0, //self.view.frame是從navigationBar下面開始計算一直到屏幕tabBar上部
UIRectEdgeTop = 1 << 0, //self.view.frame是從navigationBar上面計算面開始計算一直到屏幕tabBar上部
UIRectEdgeLeft = 1 << 1,
UIRectEdgeBottom = 1 << 2, //self.view.frame是從navigationBar下面開始計算一直到屏幕底部
UIRectEdgeRight = 1 << 3,
UIRectEdgeAll = UIRectEdgeTop | UIRectEdgeLeft | UIRectEdgeBottom | UIRectEdgeRight //布局是從navigationbar頂部開始,屏幕底部結束
} API_AVAILABLE(ios(7.0));
@property(nonatomic,assign) UIRectEdge edgesForExtendedLayout API_AVAILABLE(ios(7.0)); // Defaults to UIRectEdgeAll
邊緣延伸屬性。是視圖控制器的布局屬性,默認值是 UIRectEdgeAll
,即:當前視圖控制器里各種UI控件【本身】(而非內容)會忽略導航欄和標簽的存在,布局時若設置其原點設置為(0,0),視圖會延伸顯示到導航欄的下面被覆蓋;其值為UIRectEdgeNone意味著子控件本身會自動躲避導航欄和標簽欄,以免被遮擋。
automaticallyAdjustsScrollViewInsets
官方文檔說明
@property(nonatomic,assign) BOOL automaticallyAdjustsScrollViewInsets API_DEPRECATED("Use UIScrollView's contentInsetAdjustmentBehavior instead", ios(7.0,11.0),tvos(7.0,11.0)); // Defaults to YES
UIViewController
的一個屬性:(iOS7.0引入,11.0廢除,之后其作用被UIScrollView
的新屬性contentInsetAdjustmentBehavior
所取代,如設置為UIScrollViewContentInsetAdjustmentAutomatic
等);
作用:默認情況下,它可以保證滾動視圖的內容自動偏移,不會被UINavigationBar
與UITabBar
遮擋。
automaticallyAdjustsScrollViewInsets
的設置只對滾動視圖有效,對普通的 view 無效;對普通 view 而言,UINavigationBar
與UITabBar
半透明:會被遮擋;不透明,不會被遮擋。如果兩個都是默認情況下,則滾動視圖的內容不會被遮擋,普通的 view 會被遮擋,這是最常見的情況。
以上是自己開發(fā)項目時遇到的問題,做個筆記,方便后續(xù)查看,希望也能幫助需要的小伙伴。如有問題,請指出,謝謝