xcode9在真机上跑和xcode9 模拟器大小上跑的效果怎么不一样

iOS11、iPhone X、Xcode9 适配指南原文链接:
不断完善中。。。 更新iOS11后,发现有些地方需要做适配,整理后按照优先级分为以下三类:
单纯升级iOS11后造成的变化;
Xcode9 打包后造成的变化;
iPhoneX的适配
一、单纯升级iOS11后造成的变化
升级后,发现某个拥有tableView的界面错乱,组间距和contentInset错乱,因为iOS11中 UIViewController 的 automaticallyAdjustsScrollViewInsets 属性被废弃了,因此当tableView超出安全区域时,系统自动会调整SafeAreaInsets值,进而影响adjustedContentInset值
// 有些界面以下使用代理方法来设置,发现并没有生效
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)
// 这样的原理是因为之前只是实现了高度的代理方法,却没有实现View的代理方法,iOS10及以前这么写是没问题的,iOS11开启了行高估算机制引起的bug,因此有以下几种解决方法:
// 解决方法一:添加实现View的代理方法
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
// 解决方法二:直接使用tableView属性进行设置,修复该UI错乱
self.tableView.sectionHeaderHeight = 0;
self.tableView.sectionFooterHeight = 5;
[_optionTableView setContentInset:UIEdgeInsetsMake(-35, 0, 0, 0)];
// 解决方法三:添加以下代码关闭估算行高
self.tableView.estimatedRowHeight = 0;
self.tableView.estimatedSectionHeaderHeight = 0;
self.tableView.estimatedSectionFooterHeight = 0;
四、使用Xcode9 编译后发现的问题
1. 发现“fastSocket”第三方报错,具体原因是缺少C99的头文件,引入“#include &sys/time.h&”即可
2. 导航栏的新特性
原生的搜索栏样式发生改变
右边为iOS11样式,搜索区域高度变大,字体变大
查看 API 后发现,iOS11后将 searchController 赋值给了 NavigationItem,通过属性 hidesSearchBarWhenScrolling 可以控制搜索栏是否在滑动的时候进行隐藏和显示
// A view controller that will be shown inside of a navigation controller can assign a UISearchController to this property to display the search controller’s search bar in its containing navigation controller’s navigation bar.
@property (nonatomic, retain, nullable) UISearchController *searchController API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(tvos);
// If this property is true (the default), the searchController’s search bar will hide as the user scrolls in the top view controller’s scroll view. If false, the search bar will remain visible and pinned underneath the navigation bar.
@property (nonatomic) BOOL hidesSearchBarWhenScrolling API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(tvos);
另外,UINavigationBar 新增属性 BOOL值 prefersLargeTitles 来实现下面的效果,并可以通过 largeTitleTextAttributes 来设置大标题的文本样式
有个界面使用到了导航栏按钮相关的frame,也发生了UI错乱,查看UI层级关系后发现,iOS11以前是直接把按钮加到了UINavigationBar上面,而iOS11则是先将按钮加到了_UITAMICAdaptorView,再加到_UIButtonBarStackView、_UINavigationBarContentView,接着才是UINavigationBar。因此如果需要获取导航栏按钮
frame 或者 superView,这里需要专门做下适配
iOS10及以下版本导航栏按钮层级关系图
iOS11导航栏按钮层级关系图
三、iPhone X的适配
下载完Xcode9之后,第一件事自然是在 iPhone X(模拟器)上过把瘾,然后编译后就发现报错了 由于iPhone X的状态栏是和其他版本手机差异比较大的,因此api 变化也比较大 先后做了以下适配
适配点一:项目中使用状态栏中图标判断当前网络的具体状态
打印的 Log 报出以下错误: Trapped uncaught exception 'NSUnknownKeyException', reason: '[&UIStatusBar_Modern 0x7fcdb0805770& valueForUndefinedKey:]: this class is not key value coding-compliant for the key foregroundView.'
使用 runtime 打印其所有属性,发现以下差异
// 测试代码
#import &objc/runtime.h&
NSMutableString *resultStr = [NSMutableString string];
//获取指定类的Ivar列表及Ivar个数
unsigned int count = 0;
Ivar *member = class_copyIvarList([[application valueForKeyPath:@"_statusBar"] class], &count);
for(int i = 0; i & i++){
Ivar var = member[i];
//获取Ivar的名称
const char *memberAddress = ivar_getName(var);
//获取Ivar的类型
const char *memberType = ivar_getTypeEncoding(var);
NSString *str = [NSString stringWithFormat:@"key = %s
type = %s \n",memberAddress,memberType];
[resultStr appendString:str];
NSLog(@"%@", resultStr);
// 其他版本的手机
key = _inProcessProvider
type = @"&UIStatusBarStateProvider&"
key = _showsForeground
key = _backgroundView
type = @"UIStatusBarBackgroundView"
key = _doubleHeightLabel
type = @"UILabel"
key = _doubleHeightLabelContainer
type = @"UIView"
key = _currentDoubleHeightText
type = @"NSString"
key = _currentRawData
type = {超长。。}
key = _interruptedAnimationCompositeViews
type = @"NSMutableArray"
key = _newStyleBackgroundView
type = @"UIStatusBarBackgroundView"
key = _newStyleForegroundView
type = @"UIStatusBarForegroundView"
key = _slidingStatusBar
type = @"UIStatusBar"
key = _styleAttributes
type = @"UIStatusBarStyleAttributes"
key = _waitingOnCallbackAfterChangingStyleOverridesLocally
key = _suppressGlow
key = _translucentBackgroundAlpha
key = _showOnlyCenterItems
key = _foregroundViewShouldIgnoreStatusBarDataDuringAnimation
key = _tintColor
type = @"UIColor"
key = _lastUsedBackgroundColor
type = @"UIColor"
key = _nextTintTransition
type = @"UIStatusBarStyleAnimationParameters"
key = _overrideHeight
type = @"NSNumber"
key = _disableRasterizationReasons
type = @"NSMutableSet"
key = _timeHidden
key = _statusBarWindow
type = @"UIStatusBarWindow"
// iPhone X
key = _statusB type = @"_UIStatusBar"
// 因此可见iPhone X的状态栏是多嵌套了一层,多取一次即可,最终适配代码为:
// 不能用 [[self deviceVersion] isEqualToString:@"iPhone X"] 来判断,因为模拟器不会返回 iPhone X
if ([[application valueForKeyPath:@"_statusBar"] isKindOfClass:NSClassFromString(@"UIStatusBar_Modern")]) {
children = [[[[application valueForKeyPath:@"_statusBar"] valueForKeyPath:@"_statusBar"] valueForKeyPath:@"foregroundView"] subviews];
children = [[[application valueForKeyPath:@"_statusBar"] valueForKeyPath:@"foregroundView"] subviews];
适配点二:解决这个问题后项目跑起来发现,整个app界面上下各空出大概40pt的高度
经常从 Github 上下载项目把玩的老司机们都知道,有些老项目在模拟器上跑起来之后也会只有 iPhone 4(320*480)的布局空间,造成这个的原因是启动图使用 Launch Images Source 设置的时候没有勾选并设置对应的图片,解决方法如下
然而iPhone X更大的坑是屏幕的适配
首先看下屏幕尺寸
这张图反映出不少信息:
iPhone X的宽度虽然和7是一样的,但是高度多出145pt
使用三倍图是重点,而且一般认为肉眼所能所能识别的最高的屏幕密度是300ppi,iPhone X已达到458ppi(查证发现三星galaxy系列的屏幕密度是522ppi)
在设计方面,有明确要求,下面结合图例进行说明:
展示出来的设计布局要求填满整个屏幕
填满的同时要注意控件不要被大圆角和传感器部分所遮挡
安全区域以外的部分不允许有任何与用户交互的控件
上面这张图内含信息略多
头部导航栏不予许进行用户交互的,意味着下面这两种情况 Apple 官方是不允许的
底部虚拟区是替代了传统home键,高度为34pt,通过上滑可呼起多任务管理,考虑到手势冲突,这部分也是不允许有任何可交互的控件
状态栏在非安全区域,文档中也提到,除非可以通过隐藏状态栏给用户带来额外的价值,否则最好把状态栏还给用户
相关热门文章<div class="like-count align-center" data-v-Xcode 7:无需99刀也能在真机上测试App_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
Xcode 7:无需99刀也能在真机上测试App
51CTO视频课程|
总评分0.0|
阅读已结束,下载文档到电脑
想免费下载本文?
定制HR最喜欢的简历
你可能喜欢Xcode 现在调试一直卡在 Attaching to...上 无论真机还是模拟器 - V2EX
Xcode 现在调试一直卡在 Attaching to...上 无论真机还是模拟器
49 天前 &DendimoN
CleanMyMac 卸掉重装也不行
看网上的完整卸载教程卸掉也不行
现在真的不知道怎么才能搞好它。。
真的不想抹盘重装。。
468 次点击所在节点 &
bytelee49 天前看下 xcode 的 log 输出 找下问题
tane0549 天前Xcode 9.0 beta3 碰到一样的问题, 试试 Debug 下手动 Attach to Process.
第 1 页 / 共 1 页&
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到
上打开本讨论主题的完整版本。
是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
is a community of developers, designers and creative people.怎么Android模拟器和真机测试结果不一样的 - ITeye问答
我写个是一个Google Map的程序,在模拟器中运行时
Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
这个location = null,当程序使用location的时候有异常。
但是在真机中运行却不会
= null,所以运行正常。。。
在AndroidManifest.xml中已经加入了
&uses-permission android:name="android.permission.INTERNET"&&/uses-permission&
&uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"&&/uses-permission&
&uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"&&/uses-permission&
采纳的答案
模拟器可以模拟GPS的功能,但需要在界面上进行设置,不能直接使用。通过eclipse的DDMS视图,在模拟器进程列表下面的模拟器设置界面找到位置GPS位置设置的两个输入框,可以设置模拟器传递给后台的经纬度
已解决问题
未解决问题

我要回帖

更多关于 xcode 判断真机模拟器 的文章

 

随机推荐