標籤:ios personal hotspot 狀態列 熱點欄 changestatusbarframe
一.iPhone建立個人熱點iPhone/iOS
雙環上網,即iPhone通過建立個人熱點(Personal Hotspot)實現共用上網,支援攜帶型Wi-Fi熱點、藍芽共用網路和USB共用網路。
1.若iPhone已開啟了WiFi(和藍芽),則直接建立成功。
其他裝置可通過WiFi(或藍芽)搜尋熱點名稱並串連實現共用上網。
需要說明的是:蘋果的藍芽協議是封閉的,只支援蘋果的裝置(iPhone/iPad/iMac)間串連,無法與Android等裝置的藍芽進行發現配對!
2.若iPhone只開啟了藍芽,未開啟WiFi,則提示
若選擇【開啟"Wi-Fi"】(Turn on Wi-Fi),則其他裝置可通過WiFi搜尋熱點名稱並串連實現共用上網。
若選擇【僅藍芽和USB】(Bluetooth and USB Only),則其他裝置可通過藍芽或USB串連到該iPhone搜尋熱點名稱並串連實現共用上網。
3.若iPhone未開啟藍芽和WiFi,則提示
若選擇【開啟"Wi-Fi"和藍芽】(Turn on Wi-Fi and Bluetooth),則其他裝置可通過藍芽/WiFi搜尋熱點名稱並串連實現共用上網。
若選擇【僅USB】(USB Only),則其他裝置可通過USB串連到該iPhone搜尋熱點名稱並串連實現共用上網。
二.iMac通過USB串連iPhone共用個人熱點上網
當iPhone建立了個人熱點,iMac(Mac OS X)通過USB串連上iPhone時,將自動連接上iPhone的個人熱點(the first 1 Connection)。
在Mac/Xcode上調試iPhone真機時,若只想調試iPhone/Android串連個人熱點的情形(以便測試有熱點欄和無熱點欄的情況),則可在Network Preferences中刪除iPhone USB介面(interface),防止Mac自動通過USB串連上iPhone熱點對調試造成幹擾。
三.iPhone/iOS個人熱點狀態列iPhone作為個人熱點且有串連時,系統狀態列下面會多一行
熱點串連提示欄"Personal Hotspot: * Connection",縱向會下壓20pt;當所有串連都斷開時,熱點欄消失,縱向高度恢複正常。
1.系統狀態列
APP_STATUSBAR_HEIGHT=[UIApplication sharedApplication].statusBarFrame.size.height,包含熱點欄(如有)高度。
// iOS系統版本
#define
SYSTEM_VERSION [[[UIDevice currentDevice] systemVersion] doubleValue]
// 標準系統狀態列高度
#define
SYS_STATUSBAR_HEIGHT 20
// 熱點欄高度
#define
HOTSPOT_STATUSBAR_HEIGHT 20
// 導覽列(UINavigationController.UINavigationBar)高度
#define
NAVIGATIONBAR_HEIGHT 44
// 工具列(UINavigationController.UIToolbar)高度
#define
TOOLBAR_HEIGHT 44
// 標籤欄(UITabBarController.UITabBar)高度
#define
TABBAR_HEIGHT 44
// APP_STATUSBAR_HEIGHT=SYS_STATUSBAR_HEIGHT+[HOTSPOT_STATUSBAR_HEIGHT]
#define
APP_STATUSBAR_HEIGHT (CGRectGetHeight([UIApplication sharedApplication].statusBarFrame))
// 根據APP_STATUSBAR_HEIGHT判斷是否存在熱點欄
#define
IS_HOTSPOT_CONNECTED (APP_STATUSBAR_HEIGHT==(SYS_STATUSBAR_HEIGHT+HOTSPOT_STATUSBAR_HEIGHT)?YES:NO)
// 無熱點欄時,標準系統狀態列高度+導覽列高度
#define
NORMAL_STATUS_AND_NAV_BAR_HEIGHT (SYS_STATUSBAR_HEIGHT+NAVIGATIONBAR_HEIGHT)
// 即時系統狀態列高度+導覽列高度,如有熱點欄,其高度包含在APP_STATUSBAR_HEIGHT中。
#define
STATUS_AND_NAV_BAR_HEIGHT (APP_STATUSBAR_HEIGHT+NAVIGATIONBAR_HEIGHT)
2.UIViewController.view.bounds.height
- SYSTEM_VERSION < 7.0,UIViewController.view.bounds.height包含導覽列高度,不包含系統狀態列高度,也不包含熱點欄(如果有)。
- SYSTEM_VERSION ≥ 7.0,UIViewController.view.bounds.height包含標準系統狀態列高度和導覽列高度,但不包含熱點欄(如果有)。
也即當有熱點欄時,UIViewController.view.bounds.height都
自動扣除了熱點欄的高度,iOS<7.0不包含標準系統狀態列,iOS≥7.0包含標準系統狀態列。
由於iOS7把整個螢幕高度(包括狀態列,不包括熱點欄)都作為了視圖控制器的有效高度,因此從iOS6升級到iOS7時,會出現視圖整體上移了一個狀態列的高度(20pt),並和上層的狀態列交疊在一起。
解決方案:設定
extendedLayoutIncludesOpaqueBars屬性為NO,設定
edgesForExtendedLayout為UIRectEdgeNone。
3.UIViewController適應熱點欄範例程式碼
- (void)
viewWillAppear:(BOOL)animated
{
self.extendedLayoutIncludesOpaqueBars = NO;
self.edgesForExtendedLayout = UIRectEdgeNone;
}
// MyViewController介面繼承自UIViewController
@interface MyViewController : UIViewController
// MyViewController* myViewController入棧
MyViewController* myViewController = [[MyViewController alloc] init];
[self.navigationController pushViewController:myViewController animated:YES];
- (id)
init
{
// 初始非全屏
_bFullScreen = NO;
// 進入該UIViewController之前的狀態
_lastStatusBarStyle = [[UIApplication sharedApplication] statusBarStyle];
_lastBarTranslucent = self.navigationController.navigationBar.translucent;
}
- (void)
viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (_bFullScreen)
{
if (SYSTEM_VERSION >= 7.0)
{
self.extendedLayoutIncludesOpaqueBars = YES;
self.edgesForExtendedLayout = UIRectEdgeAll;
}
else
{
self.wantsFullScreenLayout = YES;
self.navigationController.navigationBar.translucent = YES; // iOS 6下保證導覽列透明
}
}
else
{
[[UIApplication sharedApplication] setStatusBarStyle:_lastStatusBarStyle];
if (SYSTEM_VERSION >= 7.0)
{
// 設定後:有個人熱點串連時,UIViewController.view自動下移20;無個人熱點串連時,UIViewController.view自動上移20
self.extendedLayoutIncludesOpaqueBars = NO;
self.edgesForExtendedLayout = UIRectEdgeNone;
}
else
{
self.wantsFullScreenLayout = NO;
self.navigationController.navigationBar.translucent = _lastBarTranslucent;
}
}
}
// 手動點擊內容地區實現全屏
- (void)
setFullScreen:(BOOL)bFull
{
_bFullScreen = bFull;
// 全屏(非全屏)隱藏(顯示)系統狀態列
[[UIApplication sharedApplication] setStatusBarHidden:bFullScreen];
// 全屏(非全屏)隱藏(顯示)頂部導覽列
[self.navigationController setNavigationBarHidden:bFullScreen animated:YES];
// 全屏(非全屏)隱藏(顯示)底部工具列
[self.navigationController setToolbarHidden:bFullScreen animated:YES];
// 下面計算Custom Content的Rect
if (!_supportFullScreen)
{
CGFloat contentSatrtY = 0;
if (IS_HOTSPOT_CONNECTED) {
// iPhone4(s)-iOS6/iOS7螢幕座標系下:hostView.frame={{0, 40}, {320, 440}}/{{0, 20}, {320, 460}}
contentSatrtY = STATUS_AND_NAV_BAR_HEIGHT; // 84
if (SYSTEM_VERSION >= 7.0) { // 如果設定了edgesForExtendedLayout=UIRectEdgeNone
contentSatrtY -= HOTSPOT_STATUSBAR_HEIGHT; // 64(有熱點欄時,會自動下移20)
}
} else {
// iPhone4(s)-iOS6/iOS7螢幕座標系下:hostView.frame={{0, 20}, {320, 460}}/{{0, 0}, {320, 480}}
contentSatrtY = NORMAL_STATUS_AND_NAV_BAR_HEIGHT; // 64
}
// contentSatrtY基於UIViewController.view所在的螢幕座標系進行排版
contentRect = CGRectMake(0, contentSatrtY, hostView.width, SCREEN_HEIGHT-STATUS_AND_NAV_BAR_HEIGHT-TOOLBAR_HEIGHT);
}
else
// 針對iOS6/7分別配置了wantsFullScreenLayout=YES/edgesForExtendedLayout=UIRectEdgeAll,全屏隱藏狀態列(包括熱點欄)、導覽列和工具列之後高度為SCREEN_HEIGHT。
{
contentRect = CGRectMake(0, 0, hostView.width, hostView.height);
}
}
#pragma mark UIApplicationWillChangeStatusBarFrameNotification
// 如有必要,需監聽系統狀態列變更通知:UIApplicationWillChangeStatusBarFrameNotification
- (void)handleUIApplicationWillChangeStatusBarFrameNotification:(NSNotification*)notification
{
CGRect newStatusBarFrame = [(NSValue*)[notification.userInfo objectForKey:UIApplicationStatusBarFrameUserInfoKey] CGRectValue];
// 根據系統狀態列高判斷熱點欄的變動
BOOL bPersonalHotspotConnected = (CGRectGetHeight(newStatusBarFrame)==(SYS_STATUSBAR_HEIGHT+HOTSPOT_STATUSBAR_HEIGHT)?YES:NO);
CGPoint newCenter = CGPointZero;
CGFloat OffsetY = bPersonalHotspotConnected?+HOTSPOT_STATUSBAR_HEIGHT:-HOTSPOT_STATUSBAR_HEIGHT;
if (SYSTEM_VERSION >= 7.0) { // 對沒有自動調整的部分二級、三級子View做必要的手動調整
newCenter = self.someSubView.center;
newCenter.y += OffsetY;
self.someSubView.center = newCenter;
} else { // Custom Content對應的view整體調整
newCenter = self.contentView.center;
newCenter.y += OffsetY;
self.contentView.center = newCenter; // contentView為Custom Content對應的view
}
}
@end
iPhone/iOS開啟個人熱點的縱向適配小結