iPhone/iOS開啟個人熱點的縱向適配小結

來源:互聯網
上載者:User

標籤: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開啟個人熱點的縱向適配小結

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.