1.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搜索热门名称并连接实现同享上网。
2.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热门对调试造成干扰。
3.iPhone/iOS个人热门状态栏
iPhone作为个人热门且有连接时,系统状态栏下面会多1行热门连接提示栏"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
- 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时,会出现视图整体上移了1个状态栏的高度(20pt),并和上层的状态栏交叠在1起。
解决方法:设置
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
参考
《iOS7兼容之前版本》
《iOS7适配》《iOS7
UI适配》
《iOS7遇到的1些问题及解决方法》
《iOS7用代码解决视图控制器的View整体上移问题》