作者:弦苦地址:http://blog.csdn.net/phunxm/article/details/42967035
一.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,包含熱點欄(如有)高度,標準高度為20pt,當有個人熱點連接時,高度為40pt。
// 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
也即當有熱點欄時,UIViewController.view.bounds.height都自動扣除了熱點欄的高度,iOS<7.0不包含標準系統狀態欄,iOS≥7.0包含標準系統狀態欄。
由於iOS7把整個屏幕高度(包括狀態欄,不包括熱點欄)都作為了視圖控制器的有效高度,因此從iOS6升級到iOS7時,會出現視圖整體上移了一個狀態欄的高度(20pt),並和上層的狀態欄交疊在一起。
解決方法:設置extendedLayoutIncludesOpaqueBars屬性為NO,設置edgesForExtendedLayout為UIRectEdgeNone。
3.UIViewController適應熱點欄示例代碼
// 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; // ...}// 排版時,注意logical coordinate space和device coordinate space的區別,注意frame和bounds的區別!- (void)loadView{ // ... // 計算Custom Content View的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); } // ...}- (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]; // ...}#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) { // 即使設置了extendedLayoutIncludesOpaqueBars=NO/edgesForExtendedLayout=UIRectEdgeNone,對沒有自動調整的部分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個人熱點的interface
iPhone開啟個人熱點(橋接上網)時,會多出bridge接口。
iPhone5s/iOS8.2開啟個人熱點時,遍歷可發現多出3個活躍的bridge100接口(IFF_UP),sa_family分別是AF_LINK(18)、AF_INET6(30)、AF_INET(2)。
遍歷interface的代碼片段如下:
struct ifaddrs *interfaces = nil;if(!getifaddrs(&interfaces)){ for(structifaddrs *interface = interfaces; interface; interface = interface->ifa_next) { if ((interface->ifa_flags&IFF_UP) ==IFF_UP) { log_notice("ifa_name : %s, ifa_addr->sa_family : %d", interface->ifa_name, interface->ifa_addr->sa_family); } }}if (interfaces) { freeifaddrs(interfaces); interfaces = NULL;}
參考
《iOS7兼容之前版本》
http://www.cnblogs.com/zcw-ios/articles/3340197.html
《iOS7適配》
http://blog.csdn.net/toss156/article/details/11843873
《iOS7 UI適配》
http://www.tekuba.net/wap.asp?act=View&id=344
《iOS7遇到的一些問題及解決方法》
http://blog.csdn.net/cssmhyl/article/details/17582261
《iOS7用代碼解決視圖控制器的View整體上移問題》
http://blog.csdn.net/kmyhy/article/details/20444611