我们通常所说的iPhone5屏幕尺寸为4英寸、iPhone6屏幕尺寸为4.7英寸,指的是显示屏对角线的长度(diagonal)
成都创新互联坚持“要么做到,要么别承诺”的工作理念,服务领域包括:成都网站设计、成都做网站、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的海原网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!
PPI(Pixel Per Inch by diagonal):表示沿着对角线,每英寸所拥有的像素(Pixel)数目。
PPI数值越高,代表显示屏能够以越高的密度显示图像,即通常所说的分辨率越高、颗粒感越弱。
根据勾股定理
计算结果稍有出入,这是因为像素的离散采样有锯齿效应。
早期的iPhone3GS的屏幕分辨率是320*480(PPI=163),iOS绘制图形(CGPoint/CGSize/CGRect)均以point为单位(measured in points):
后来在iPhone4中,同样大小(3.5 inch)的屏幕采用了Retina显示技术,横、纵向方向像素密度都被放大到2倍,像素分辨率提高到(320x2)x(480x2)= 960x640(PPI=326), 显像分辨率提升至iPhone3GS的4倍(1个Point被渲染成1个2x2的像素矩阵)。
在同样的逻辑坐标系下(320x480):
为了自动适应分辨率,系统会根据设备实际分辨率,自动给UIScreen.scale赋值,该属性对开发者只读。
在同样的逻辑分辨率下,可以通过scale参数识别是iPhone3GS还是iPhone4(s)。以下基于nativeScale参数,定义了探测机型是否为iPhone6+的宏
--------------------------------------------------------------------------------那么,同样的分辨率和scale,如何区分机型iPhone4与4s、iPhone5与5s呢?通过[[UIDevice currentDevice] model]只能判别iPhone、iPad、iPod大类,要判断iPhone具体机型型号,则需要通过sysctlbyname("hw.machine")获取详细的设备参数信息予以甄别。
iPhone3GS时代,我们为一个应用提供图标(或按钮提供贴图),只需要icon.png。针对现在的iPhone4~6 Retina显示屏,需要制作额外的@2x高分辨率版本。
Phone6+在实际渲染时,downsampling/1.15(1242x2208-1080x1920),准确的讲,应该是@2.46x。苹果为方便开发者用的是@3x的素材,然后再缩放到@2.46x上。
参考: 一张图帮你看懂 iPhone 6 Plus 屏幕分辨率
1
该方法使用系统缓存,适合表视图重复加载图像的情形。同时该API根据UIScreen的scale,自动查找包含对应高倍图后缀名(@2x)的文件,如果找到二倍图,则image.scale=2.0,对应逻辑size大小以point度量(pixel度量的一半);如果没找到设置默认image.scale=1.0,对应逻辑size大小同像素尺寸。因此,
2
这组方法创建的UIImage对象 没有使用系统缓存 ,并且指定文件名必须包含明确的高倍图后缀。
3
//考虑 转屏 的影响,按照实际屏幕方向(UIDevice Orientation)的宽高
//不考虑转屏的影响,只取竖屏(UIDevice OrientationPortrait)的宽高
待续
Come on! 来看看 主流的适配方案吧
随着苹果发布两种新尺寸的大屏iPhone 6,iOS平台尺寸适配问题终于还是来了,移动设计全面进入“杂屏”时代。看看下面三款iPhone尺寸和分辨率数据就知道屏幕有多杂了。
当然除了这三种还有iPhone4 屏幕是 640*960,加起来就有四种屏幕了,你有没有感觉很复杂,发过愁吗,我们来慢慢分析下
加上Android生态中纷繁复杂的各种奇葩尺寸,现在APP设计开发必须考虑适配大、中、小三种屏幕。所以如何做到交付一套设计稿解决适配大中小三屏的问题?设计和开发之间采用什么协作模式?一个基本思路是:
1、选择一种尺寸作为设计和开发基准;
2、定义一套适配规则,自动适配剩下两种尺寸;
3、特殊适配效果给出设计效果。
来看一下手机淘宝的iPhone 6/iPhone 6 Plus采用的协作模式,再慢慢说明原委。
第一步,视觉设计阶段,设计师按宽度750px(iPhone 6)做设计稿,除图片外所有设计元素用矢量路径来做。设计定稿后在750px的设计稿上做标注,输出标注图。同时等比放大1.5倍生成宽度1125px的设计稿,在1125px的稿子里切图。
第二步,输出两个交付物给开发工程师:一个是程序用到的@3x切图资源,另一个是宽度750px的设计标注图。
第三步,开发工程师拿到750px标注图和@3x切图资源,完成iPhone 6(375pt)的界面开发。此阶段不能用固定宽度的方式开发界面,得用自动布局(auto layout),方便后续适配到其它尺寸。
第四步,适配调试阶段,基于iPhone 6的界面效果,分别向上向下调试iPhone 6 plus(414pt)和iPhone 5S及以下(320pt)的界面效果。由此完成大中小三屏适配。
为什么选择iPhone 6作为基准尺寸?
当面对大中小三种屏幕需要适配的时候,很容易想到先做好一种屏幕,再去适配剩下两种屏幕。第一个决定是到底以哪种屏幕作为设计和开发的基准尺寸。我们选择中间尺寸的iPhone 6(750px/375pt)作为基准,基于几个原因:
1、从中间尺寸向上和向下适配的时候界面调整的幅度最小。375pt下的设计效果适配到414pt和320pt偏差不会太大。假设以414pt为基准做出很优雅的设计,到320pt可能元素之间比例就不是那么回事了,比如图片和文字之间视觉比例可能失调。
2、iPhone 6 plus有两种显示模式,标准模式分辨率为1242x2208,放大模式分辨率为1125x2001(即iPhone 6的1.5倍)。可见官方系统里iPhone 6和iPhone 6 plus分辨率之间就存在1.5倍的倍率关系。很多情况下这两种尺寸可以用1.5倍直接等比适配。
3、1242x2208这个奇葩的数值是苹果官方都不愿意公开宣传的一个分辨率,不便于记忆和计算栅格。640x1136虽然是广泛应用的一个分辨率,但是大屏时代依然以小尺寸为设计基准显然不合时宜,设计师会停留在小屏的视角做设计。
所以,iPhone6的750x1334是最适合基准尺寸。
只交付一套设计稿,默认用什么规则来适配?
前文提到适配策略是先选择iPhone 6作为基准设计尺寸,然后通过一套适配规则自动适配到另外两种尺寸。这套适配规则总结起来就一句话:文字流式,控件弹性,图片等比缩放
控件弹性指的是,navigation、cell、bar等适配过程中垂直方向上高度不变;水平方向宽度变化时,通过调整元素间距或元素右对齐的方式实现自适应。这样屏幕越大,在垂直方向上可以显示更多内容,发挥大屏幕的优势。
按照上述默认适配规则,大中小三种屏幕显示效果均相同。有时候想在大屏幕显示更多内容,需要设计出特殊适配效果。比如App store首页焦点图,从iPhone 6适配到iPhone 6 plus时焦点图尺寸和排版做了特殊处理。底下应用列表也从一排3+个变成一排4+个,真正实现了大屏幕显示更多内容的理念。这些就需要设计师给出相应设计稿。
读完你懂了吗,如果有疑问,欢饮留言跟我讨论╰( ̄▽ ̄)╮
原文地址
在iOS开发中,有些公司对字体也有适配要求,为了让字体美观,所以在不同尺寸的屏幕上字体大小也要做到适配。
自己总结了几种方法供大家参考。
方法一:用宏定义适配字体大小(根据屏幕尺寸判断)
方法二:用宏定义适配字体大小(根据屏幕尺寸判断)
方法三:(利用runTime给UIFont写分类 替换系统自带的方法)推荐使用这种
外部正常调用系统设置字体方法就行
注意:
作者链接:
Swift版导航栏适配参考
在iOS 13中给导航的 UINavigationBar 增加了 scrollEdgeAppearance 属性应用在iOS 14及更早版本的大标题导航栏上,在iOS 15中 scrollEdgeAppearance 属性适用于所有的导航栏
官方解释:描述当关联的UIScrollView到达与导航条相邻的边缘(导航条的上边缘)时要使用的导航条的外观属性。如果没有设置,将使用修改后的standardAppearance
scrollEdgeAppearance 与 standardAppearance 一样同属于 UINavigationBarAppearance 类型 父类是 UIBarAppearance
其中影响导航栏颜色、阴影涉及到以下属性
因为 scrollEdgeAppearance = nil ,当前控制器如果使用有 ScrollView 类的控件,当 ScrollView 向上滚动时 scrollEdgeAppearance 会默认使用 standardAppearance 的属性效果。所以 backgroundEffect 和 shadowColor 属性需要显式设置为nil,以防止 backgroundEffect、shadowColor 有颜色值影响导航栏透明效果。
下一篇:Swift版导航栏适配
PERFECT!
基本上每个IOS APP都会有新手引导页面这个功能,常规的就是几张静态图片,可以左右滚动。既然涉及到图片,就肯定会存在适配的问题(为了达到最优的体验效果,一般都会针对不同的分辨率设计不同尺寸的图片),本文主要就是讨论如何适配的问题。
2.1 方案一
根据屏幕分辨率的不同,使用不同的图片。
2.2 方案二
熟悉IOS开发的人都知道,每一个ios项目中,都有一个Assets.xcassets文件夹,用来管理项目中所有的图片(AppIcon、LaunchImage、其他业务图片)。
从上面的截图我们可以看到,xcode提供了两个内置的类型AppIcon、LaunchImage。我们只要提供正确尺寸的图片,ios系统就能在不同分辨率的设备上使用对应的图片而无需我们自己指定;另外就是我们自己创建的(avatar),提供2x、3x这两种类型的图片即可(1x的设备现在基本上找不到了,而且当前的ios系统也不支持1x的设备)。那么问题来了,我们自己创建的图片集合,只有3个类型(1x、2x、3x),并不能按照分辨率来设定。再看一下上面的截图,有一个“show”的图片集合,形式如下:
咦!这个鬼东西是怎么搞出来的?我们先看看Assets.xcassets文件夹在硬盘上的组织形式:
从上图我们可以看到,系统内置的两种类型AppIcon、LaunchImage对于的文件夹为AppIcon.appiconset、LaunchImage.launchimage,我们自己创建的图片集合avatar对应的文件夹为avatar.imageset。讲到这里,你应该大概猜到了show这个图片集合是怎么创建出来了吧?
1、先创建一个LaunchImage类型的图片集合;
2、修改名称(LaunchImage→show)
3、修改文件夹名称(show.launchimage→show.imageset)
回到正题,在show这个图片集合里面,我们就可以轻松的根据分辨率设置2x、3x类型的图片。
现在我们可以按照下图的方式使用新手引导图片了:
亲测:不同分辨率的设备,展示对应的图片。
我们注意到,show.imageset文件夹中有一个文件Contents.json,正是这个文件,ios系统才能根据设备类型展示对应的图片资源。Contents.json文件内容如下:
系统展示图片的时候,会先解析这个文件,然后根据设备的分辨率,找到对应的图片。
在iOS11以前, 自定义UIViewController时, 从来没有考虑过topLayoutGuide和bottomLayoutGuide这两个属性.但是在iOS11出来之后,这两个属性被废弃,取而代之的就是safeArea的概念,safeArea是描述你的视图部分不被任何内容遮挡的方法。 它提供两种方式:safeAreaInsets或safeAreaLayoutGuide来提供给你safeArea的参照值,即 insets 或者 layout guide。 safeArea区域如图所示:
在除了iPhone X以外的型号手机上, UINavigationController 就是 topLayoutGuide区域. UITabBarController就是bottomLayoutGuide.但是这两个属性在iOS11已经被取代了. 取而代之的就是safeArea区域(iPhone X图区域4部分)
当我们自定义一个UIViewController, 内部嵌套了UINavigationController 或者UITabBarController的时候. 运行程序会出现以下错误:
原因是少了:
具体是为什么,没有细研究.不过解决办法如下:
因为我是创建的空项目所以只有LaunchScreen.storyboard..如果你的项目里还有Main.storyboard,那么 你需要把第四个勾勾也去掉.
区域一: 高度30
区域二:高度14
区域三:高度44
区域五:高度49
区域六:高度14
区域七:高度20
更新iOS11以后, UITabBarController上的图标文字由原来的垂直放置, 变成水平放置
iPhone X 横竖屏在尺寸上有很多细微的差别.
我们打印UINavigationController navigationBar的时候发现他的高度为44.也就是上图绿色区域.但是在实际显示的时候确实红色区域,高度为32.整个高度向上12.也就是蓝色区域.
我们打印UITabBarController tabBar的时候发现他的高度为32,就是橘色区域,红色区域为功能区,高度为21.我们是何止tabBar颜色的时,包括橘色区和红色区.
待更新
解决方案: 准备一张尺寸:1125 * 2436的启动图片, 添加到Assret中
解决方案: 通过改变按钮的 contentEdgeInsets和imageEdgeInsets的值成功改变了按钮的偏移问题,单独设置contentEdgeInsets也可达到一定的效果。
解决方案:iOS11弃用了automaticallyAdjustsScrollViewInsets属性,新增contentInsetAdjustmentBehavior来替代它
- (void)createView:(BOOL)useForRendering showRightAway:(BOOL)showRightAway;
{
if(_view == nil)
{
NSString *deviceVersion = [self getDeviceVersion];
if ([deviceVersion isEqualToString:@"iPhone10,3"] || [deviceVersion isEqualToString:@"iPhone10,6"])
{
CGRect bounds = CGRectMake(34, 0, 744, 375);
_window = [[UIWindow alloc] initWithFrame:bounds];
}
else
{
_window = [[UIWindow alloc] initWithFrame: _screen.bounds];
}
_window.screen = _screen;
if(_screen == [UIScreen mainScreen])
{
_view = [[GetAppController() init] unityView];
NSAssert([_view isKindOfClass:[UnityView class]], @"You MUST use UnityView subclass as unity view");
}
else
{
_view = [(useForRendering ? [UnityRenderingView alloc] : [UIView alloc]) initWithFrame: _screen.bounds];
}
_view.contentScaleFactor = UnityScreenScaleFactor(self.screen);
[self updateScreenSize];
if(showRightAway)
{
[_window addSubview:_view];
[_window makeKeyAndVisible];
}
}
}
- (NSString*)getDeviceVersion
{
struct utsname systemInfo;
uname(systemInfo);
NSString *deviceVersion = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
NSLog(@"添加获取手机型号方法 ++ %@", deviceVersion);
return deviceVersion;
}
- (void)updateScreenSize
{
CGSize layerSize = _view.layer.bounds.size;
NSString *deviceVersion = [self getDeviceVersion];
if ([deviceVersion isEqualToString:@"iPhone10,3"] || [deviceVersion isEqualToString:@"iPhone10,6"])
{
layerSize = CGSizeMake(744, 375);
}
CGFloat scale = UnityScreenScaleFactor(_screen);
_screenSize = CGSizeMake(layerSize.width * scale, layerSize.height * scale);
}