当前位置: 首页 > 科技观察

如何让一套代码适配所有iOS设备尺寸?

时间:2023-03-15 22:28:11 科技观察

随着移动互联网设备和技术的发展,各种屏幕尺寸的移动设备层出不穷,折叠屏、分屏、悬浮窗等,面对越来越多样化的屏幕,如果每一种尺寸都单独适配,不仅费时费力,而且增加了端侧代码的开发和维护压力。如何让一套代码适配所有尺寸的变化,增强应用的通用能力?阿里娱乐科技氚雨将分享优酷APP在iOS响应式布局技术的实践与实现。响应式是基于同一套代码。开发一个APP可以兼容多尺寸、多终端设备的显示。可以动态调整页面布局和容器布局,充分利用当前屏幕尺寸,为用户提供更好的浏览体验。APP开发效率和迭代效率。一、iOS布局尺寸预研目前iOS端主要有五种尺寸类型:iPhone、iPad竖屏、iPad横屏、iPad悬浮窗、iPad分屏。通常,App是根据iPhone尺寸开发的,需要适配其余四种iPad尺寸。iPad的横屏和竖屏比较常见,只需旋转设备,悬浮窗和分屏模式比较特殊。从苹果iPadiOS9开始,用户在打开一个应用时,可以从底部向上滑动打开Dock,然后拖动另一个应用进入浮窗模式:将其拖到支持分屏的iPad边缘启用分屏屏幕模式:所有升级到iOS9的设备都支持悬浮窗模式,只有最新的硬件设备iPadmini4、iPadAir2和iPadPro支持分屏模式:设备悬浮窗splitscreen设备悬浮窗分屏iPadmini2?iPadmini3?iPadmini4??iPadAir?iPadAir2??iPadPro??2.优酷iOS响应式解决方案响应式布局的核心是设计一个统一的适配规则,当screensizechanges根据布局规则重新布局,以适应不同的屏幕尺寸,而大多数应用在开发时一般只有适配iPhone的版本。通过responsiveness适配更多模型时,主要需要解决三个问题,分别是如何获取和更新对应适配的responsive状态,如何计算不同情况下App内容的宽度、列数等布局参数屏幕宽度,以及如何进行响应式数据处理,解决难以适配的组件,减少页面留白等。基于此,我们开发了响应式布局SDK,负责响应式状态的统一管理,处理布局逻辑和裁剪映射数据。响应式SDK在App中的位置1.响应式App配置除了将App配置为通用版外,还需要一些配置来支持悬浮窗或者分屏模式:(1)需要提供LaunchScreen.storyboard作为启动图,因为App支持的运行尺寸太多,用图片作为启动图已经不合适了。(2)需要在info.plist中配置对所有屏幕方向的支持:(3)注意不要勾选Requiresfullscreen配置项或配置UIRequiresFullScreen为YES。这里会声明App需要全屏运行,自然也就意味着不支持悬浮窗或者分屏:(4)支持分屏需要App的主窗口需要使用系统UIWindow,不能继承,必须通过init方法或initWithFrame:[UIScreenmainScreen].bounds进行初始化。通过以上步骤开启悬浮窗和分屏能力后,就无法再通过APP中的相关代码来控制设备方向了。以前可以通过下面的代码来控制ViewController为竖屏。支持分屏后,系统将不再调用以下方法,所有默认的ViewController都支持所有屏幕方向:如下强制屏幕方向的黑色方法也无效:这样设计的主要原因是当一个应用程序支持分屏,不再单独占据整个屏幕。当另一个应用程序同时运行时,不可能在同一屏幕上出现一个横屏和另一个竖屏。这类问题没有完美的解决方案。为了保证用户体验,支持分屏的应用必须让所有页面适配所有屏幕方向。这也体现了苹果对用户体验的极致追求。参见DeveloperForums中开发者的讨论:https://developer.apple.com/forums/thread/195782,ResponsiveSDKResponsiveStateManagementResponsivestate提供是否开启响应、响应布局大小类型、当前布局窗口等相关状态量尺寸等响应式SDK屏幕尺寸变化后会更新响应状态,通过系统通知和自定义通知机制通知相关业务方。//响应式开启/关闭状态typedefNS_ENUM(NSInteger,YKRLLayoutStyle){YKRLLayoutStyleNormal=0,//响应式关闭YKRLLayoutStyleResponsive=1,//响应式开启};//响应式屏幕尺寸类型,页面可以根据该类型来区分是否分屏等typedefNS_ENUM(NSInteger,YKRLLayoutSizeType){YKRLLayoutSizeTypeS=0,//eg.phonepad浮窗YKRLLayoutSizeTypeL=1,//padYKRLLayoutSizeTypeXL=2,//reserved};//响应式屏幕状态类型(共十种类型)typedefNS_OPTIONS(NSUInteger,YKRLLayoutScreenType){YKRLLayoutScreenTypeUnknown=(1<<0),//未知YKRLLayoutScreenTypePortrait=(1<<1),//垂直全屏YKRLLayoutScreenTypeLandscapeLeft=(1<<2),//水平全屏左...};响应式SDK声明了YKRLLayoutStyle、YKRLLayoutSizeType、YKRLLayoutScreenType三个枚举状态来标记当前响应状态,分别表示响应式开闭状态、当前尺寸类型和具体屏幕类型。一般业务方只需要获取是否为Responsive设备状态即可,对于不同宽度下页面布局不一致的业务方,可以通过sizetype状态进行区分和适配,对于需要了解当前屏幕状态的业务方detail,可以通过screentype获取,它只包括当前iOS设备支持的屏幕状态,随着设备类型的丰富,比如折叠屏等,屏幕类型也会相应的扩展。每当设备旋转或用户打开分屏时,响应式SDK会在系统回调中更新当前响应式状态,并通知业务方响应式状态的变化。响应式布局规则优酷的响应式布局规则主要包括列数适配规则、宽度适配规则等,对于每一种布局规则,在响应式SDK中都有对应的布局适配逻辑。响应式布局规则满足优酷App整体UI规范,业务方直接指定自己需要的规则。是的,除了少数特殊规则外,大部分布局规则都用于组件列数和组件宽度布局。这种响应式布局规则会指定一个标准宽度,并根据组件的原始布局列数和标准宽度来计算组件。标准宽度,然后根据当前屏幕宽度计算适配的组件列数,可以用以下公式表示:响应式适配列数(标准屏幕宽度下的组件列数)=(当前屏幕宽度÷(标准屏幕width÷standard屏幕宽度下的组件列数×scale))其中,scale为组件放大参数,标准屏幕宽度下组件的原始宽度会因为太小而无法放在iPad上,可以通过scale参数适当放大。主页提要流中的列数随屏幕宽度而变化。对于组件宽度适配,响应式规则会先计算标准屏幕宽度下的组件列数,并进行列数适配。通过自适应列数计算自适应宽度:响应式自适应宽度(标准屏幕宽度下的组件宽度)=(当前屏幕宽度-边距间距)÷响应式自适应列数(标准屏幕宽度÷标准屏幕宽度下组件的宽度)水平滑动组件在不同屏幕宽度下的组件宽度变化。调整上述公式中的标准屏幕宽度和组件缩放比例,得到一个适配效果更好的通用布局规则。经过设计,同学们可以在各种设备尺寸下进行调整总结,优酷目前使用的标准屏幕宽度为440dp,比例为1.2倍,适配效果最好。响应式SDK布局规则中已经统一实现了组件适配逻辑,业务方可以直接调用,也方便设计同学统一调整整个App的组件适配。ResponsiveSDK中的YKRLCompLayoutManager类封装了相关的布局逻辑。业务方也可以使用YKRLCompLayoutAdapterProtocol协议进行二次处理,自定义响应式布局逻辑。在App统一架构下,直接调用YKRLCompLayoutManager的相关接口,根据响应式规则获取计算。布局参数,如列数、宽度等,可以在监听响应状态时重新布局,完成响应式布局。响应式数据处理响应式数据处理包括数据映射、数据过滤、数据合并和数据补全。两端的数据处理逻辑是一致的。详见:一个APP如何适配安卓多终端?这里简单介绍一下iOS对ReactiveDataMapping的实现。有些组件无法通过规则适配不同的屏幕尺寸,比如手机上占据整个屏幕宽度的组件(下图左侧的视频播放预约组件),如果使用比例缩放的适配规则,则iPad端会显得太多。大,这样的组件可以映射成相对简单的组件来适应不同的屏幕尺寸。约会组件很难适配视频播放。映射适配预约组件,无需回放。优酷采用统一抽象的数据结构,在组件映射方面实现起来比较容易。只需要修改对应??的组件标识即可。由于统一架构的广泛推广和使用,我们在统一架构中加入了组件映射能力,方便各业务方调用。响应式SDK提供数据裁剪映射规则,业务方可以查询和添加相应的裁剪映射规则。.对于未接入统一架构的业务方,需要业务方进行相关的数据处理。3响应式业务流程3.响应式业务流程优酷的响应式业务流程是两端一致的。响应式布局需要数据处理、响应式状态管理、触发布局等,优酷的响应式SDK会在接口返回后处理相关数据,为统一架构提供相应的布局接口,监听屏幕尺寸变化和触发布局等。4.优酷的响应式解决方案在iOS开发中实现。经常使用绝对布局,实现响应式的主要任务就是变“绝对布局”为“相对布局”。接入工作比安卓繁琐。可以在Window->ViewController->Container->Component级别访问iOS响应能力。Window配置支持分屏后会由系统自动布局,RootViewController树中的子ViewController也会随Window自动布局,特殊的ViewController,比如multi的子ViewController-tab页,没有添加到RootViewController树中,需要手动修改为relative。布局,页面可以通过Autoresizing或者监听响应状态实现相对布局。访问统一架构的页面容器由统一架构提供。统一架构容器的布局列数管理和布局宽度管理已经接入响应式SDK,减少了业务方接入的大量工作。业务方只需要指定自己采用的布局规则就足够了。ViewController和容器实现相对布局后,每当屏幕尺寸发生变化时,ResponsiveSDK会通知容器重新布局,改变组件列数或宽度等,组件卡片只需要根据容器提供的尺寸布置。能。框架绝对布局一般用在组件卡中,需要修改为相对布局。使用Autoresizing可以实现简单的布局逻辑,方便快捷。复杂的布局可以使用AutoLayout或者Masonry等自动布局框架实现(性能较差),或者在layoutSubviews方法中重新计算布局,业务方可以选择合适的方法实现自动布局,降低访问成本.对于未接入统一架构的页面,需要在本页面的布局逻辑中手动接入响应式SDK的相关布局接口。优酷Responsive大图3、优酷Responsive结果实现过程中,发现很多组件卡片布局依赖于屏幕宽度,不符合响应式开发规范,导致适配Responsive时工作量大。每层View应该只依赖父层View的布局。实现各层View的相对布局后,每当屏幕尺寸发生变化时,各层View会自动适配,组件列数和容器大小会根据响应式规则进行适配,一套代码就可以适配所有屏幕尺寸,实现响应式布局。优酷响应式三大成果目前,优酷全端具备响应式布局能力,8月已上线通用版。一套代码支持iPhone、iPad竖屏、iPad横屏、悬浮窗、各种比例的分屏,为用户提供更好、更丰富的用户体验。优酷通用版首页竖屏、横屏、分屏特效优酷通用版IV播放页面竖屏、横屏、分屏特效。总结响应能力是多端交付能力的第一步。优酷实现响应式布局后,对开发、设计和产品提出了更高的要求,鉴于低端iPad设备占比较高,在业务发展过程中,不仅要考虑投资能力,还要考虑要求App始终保持较高的性能和稳定性。这就是我们继续做的事情。努力工作。苹果将??于2020年底推出基于ARM架构的MacBook,也有媒体曝光。苹果正在申请与折叠屏相关的专利。相信未来苹果设备的尺寸会越来越丰富。响应式开发大大扩展了iPhone版app的适用场景,是一种更好的多设备支持方式,为以后适应更复杂的设备场景打下了坚实的基础。【本文为专栏作者《阿里巴巴官方技术》原创稿件,转载请联系原作者】点此查看作者更多好文