作者 | 刘欣

责编 | 郭芮

每年iOS SDK的升级对于从事iOS开发的同学来说,犹如噩梦一般,因为每次升级都会带来大大小小的坑。相信每个iOS开发者都体会过其中的辛酸。今天和大家分享一下我的一个与此相关的填坑经历。记得那年,iPhone4和iPad2横空出世,是市面上的主流机型,iOS SDK版本还是4.3。

功能需求

当时做的一个功能要求简化后大概是这样的:当前UIViewController是固定的,也就是不会pop当前的UIViewController,也不会push或者present新的UIViewController。当前UIViewController对应的UIView是分页的,左右滑动可以切换页面。这个功能要求是,左右滑动切换页面时,需要根据目标页面的方向设置,有时候需要强制旋转目标页面。比如,当前iPad的方向是横向(landscape),我向右滑动切换到第二页时,第二页只支持纵向(portrait)方向,此时需要将这一页强制转换为纵向方向。

最早的实现

众所周知,苹果一个比较坑的地方就是开放的SDK是比较有限的,特别是当时的iOS SDK 4.3。很多功能通过开放的API很不好实现,上述的功能就是一个例子。当然,这难不倒我策天才般的iOS开发同学。一会就试出来实际上UIViewController上有一个私有方法(private method)就叫[UIViewController rotate],提供的功能刚好就是我们需要的。但遗憾的是由于苹果审核机制,它是不允许上架app中使用iOS SDK的私有方法的。(至今我还是不明白为什么这个方法不给开放出来给大家用。)经过进一步的研究,我们尝试出来的一个解决方法是这样的:

就是在当前的UIViewController上present一个新的UIViewController,然后马上再dismiss掉。看起来好像啥事都没做。实际上这几行代码的唯一作用是让系统(UIKit)重新评估(re-evaluate)当前UIViewController应该处于的方向,也就是说旋转相关的系统回调函数[UIViewController shouldAutorotate]和[UIViewController supportedInterfaceOrientations]会被再次调用。此时我们可以趁机在这两个回调函数中返回合适的值,使得当前的UIViewController的方向强制变成我们所希望的。

赞,一个略显tricky但是完美的解决方案!产品经理看了很满意,皆大欢喜。

第一个坑来了

这个功能一直很好用,bug也基本没有。一切都这么完美,直到一年多后,某测试同学手里捧着升级到iOS 5.0的iPad急吼吼跑到我们的开发同学面前,“粗大事了!这功能完全挂了!”(BTW,该测试同学目前已然是我司资深测试架构师)。稍微调试一下就发现原因是在iOS SDK 5.0中,上面的这几行代码调用完以后,这次系统(UIKit)并不会重新评估当前UIViewController应该处于的方向,也意味着我们并没有机会来改变当前UIViewController的方向了。苍天啊,大地啊!苹果你咋这么坑呢?行为改了也不说一声?其实前面那个方法苹果也没有在开发文档里提过,完全是靠大家自己试出来的,所以这个方法不管用了,也的确没地说理去。

如果找不到新的解决方法,可是会产生严重的regression的!经过开发同学的不懈努力,愣是又找到一个方法:

其原理和上面那个方法类似。反正就是要迫使系统(UIKit)重新评估当前UIViewController应该处于的方向。

赞,新的解决方案!Make MSTR mobile app great again!

第二个坑来了

又过了一年多,iOS6发布,还是上面那位测试同学拿着升级后的iPad又过来了,脸上写着“我就知道会这样”。说到:“额…你们快来看看!这个功能好像又挂了!”。当时我们的第一反应是iOS5的那个方法又不管用了,调试后确认果然是的。然后仔细看了iOS SDK 6的文档,这次方向和旋转又换了新玩法:

意思我们这次需要当前的UIViewController和它所在的UINavagationController一起改。于是新的解决方案是这样的,对于UIViewController,代码又变回和iOS4一样了:

对于UINavagationController,我们需要继承或者使用method swizzling来改变[UIViewController shouldAutorotate]和[UIViewController supportedInterfaceOrientations]这两个回调函数的实现:

终于,在接下来的几年中,iOS SDK的升级都没有影响这个功能了。然而最近又出现了与这个功能相关的一个bug。连续多次的意外让我对相关代码产生了怀疑。最后,我眼中望着桌上一堆装有不同iOS版本的iPhone和iPad,手里抚摸着如丝般顺滑硬件指数爆表的iPhone Xs,鬼魅般的灵感涌上心头。我突然想到了一个终极完美解决方案,以保证这些相关代码再也不会因为iOS SDK升级出问题了。

最终方案

我说服产品经理把这个功能去掉了。

作者:刘欣,微策略架构师。毕业于清华大学电子系,2007年加入微策略。参与过微策略多个产品的研发,包括可视化引擎、移动端应用。目前负责微策略管理工具以及REST服务器的研究开发工作。

声明:本文为作者投稿,版权归其所有。

【END】

这些项目,击败90%的AI工程师!

https://edu.csdn.net/topic/ai30?utm_source=csdn_bw

 热 文 推 荐 

☞我做游戏开发这八年

☞停就删稿!这个“可怕”的 GitHub 开源项目值得一试

开学季,复旦老师教你玩转“0”“1”浪漫!| 人物志

☞Google 警告开发者:所有 Android App 需要三天的审核时间!

漫画:程序员等级图鉴

☞如何用知识图谱挖掘商业数据背后的宝藏?

☞福利 | 送你一张通往「2019 AI开发者大会」的门票

92年小哥绞尽脑汁骗得价值800万比特币, 破案后警方决定还给受害者

☞微服务架构到底是什么鬼?

☞如何写出让同事无法维护的代码?

你点的每个“在看”,我都认真当成了喜欢

那些年 iOS 升级踩过的坑!相关推荐

  1. flutter ios上踩的一个坑

    在ios模拟器上调试的时候出现错误信息:The iOS Simulator deployment target is set to 4.3... 原来是因为ios 版本问题,于是找到资料是在 Podf ...

  2. Spring boot升级到2.3.2.Release和Spring framework升级到5.28.Release踩过的坑

    目录 1. 利用下面方法启动spring boot 项目是系统参数不生效 2. org.drools.template.parser.DecisionTableParseException: Fail ...

  3. Hibernate升级到5.4.18.final的过程踩过的坑

    目录 1. 抛javax.persistence.TransactionRequiredException异常,在没有事务时 2. 执行save/insert/delete相关的DB操作后,没有生效也 ...

  4. 【iOS内购支付】Uniapp拉起苹果内购支付注意事项、实现步骤以及踩过的坑(手把手教程)

    前言 Hello!又是很长时间没有写博客了,因为最近又开始从事新项目,也是第一次接触关于uniapp开发原生IOS应用的项目,在这里做一些关于我在项目中使用苹果内购支付所实现的方式以及要注意的事项,希 ...

  5. Redis 集群部署及踩过的坑

    本文目标 要在单台机器上搭建Redis集群,方式是通过不同的TCP端口启动多个实例,然后组成集群,同时记录在搭建过程中踩过的坑. 安装准备 centos版本:6.7 redis版本:3.2.3 安装方 ...

  6. AWS Device Farm介绍及Appium踩过的坑

    本文记录了在AWS Device Farm上进行Appium TestNG进行手机应用UI自动化测试的流程及遇到的问题,及具体的解决方法.同时记录了使得测试脚本更稳定的一些代码写法. Device F ...

  7. arcgis python 二次开发_我在部署ArcGIS API for Python时踩到的坑

    ArcGIS API for Python相比于其他ESRI产品,还是很年轻.我在部署时踩到了坑,网上也找不到解决方法,很是煞风景,也很打击学习的积极性. 今天回顾一下,做个总结吧.一方面自己备忘,另 ...

  8. vSAN一次人肉工程师踩过的坑

    vSAN一次人肉工程师踩过的坑 原创 李严省 虚实之路 2017-04-16 大家星期天好,这几天阳光不错,是个带家人或者女朋友出去转转的好时候.可惜这二天一夜做了VMwarevSAN人肉工程师,这二 ...

  9. 用vant框架做H5时踩过的坑(下拉刷新、上拉加载等)

    用vant框架做H5时踩过的坑 1. 页面在手机端不能上下滑动,在PC端浏览器正常滑动 说明:在设置了overflow:auto;属性的前提下,H5页面在PC端浏览器里展示可以上下滑动,在ios上可正 ...

最新文章

  1. Docker入门六部曲——Swarm
  2. html5标签 H5标签
  3. 使用触发器即时同步两个表的实例
  4. 029_Loading加载
  5. poj-1042 nyoj-30(Gone fishing)
  6. SQLServer之删除存储过程
  7. springMvc的一些简介 和基于xml的handlerMapping基本流程
  8. 推荐系统知识梳理——矩阵分解
  9. 和vs版本关系_教学鉴定贴:如何判断是不是VS厂的沛纳海手表
  10. 【TDS学习文档5】IBM Directory schema的管理3——attributes
  11. git学习(八)pull,fetch,merge
  12. Sql server 2008 R2 导出/导入数据报错之无法打开全局共享内存以与性能 DLL 通信
  13. 最新android APP框架介绍
  14. 我的专业作文300字计算机,以我的专业为题的作文(以我写一篇作文300字)
  15. 蓝桥杯五4史丰收速算
  16. 真实案件之:意料之外的 RAC 宕机罪犯 - 子游标
  17. vue中px 转 vh/vw
  18. (十五:2020.08.28)CVPR 2013 追踪之论文纲要(译)
  19. 【C++】什么是对象?什么是类?
  20. 语录集人生---投资

热门文章

  1. [LibTorch] 指定参数不进行学习
  2. 趣味物理中的计算机科学,【趣味物理】10个有趣的科学实验,揭示物理原理。...
  3. 有人做linux源码注释嘛,linux内核工作队列讲解和源码详细注释
  4. 命令窗口ping oracle,Oracle中tnsping命令解析
  5. Docker笔记4 端口映射和容器互联
  6. 中国农业机械化行业市场供需与战略研究报告
  7. 2021-2025年中国云计算数据中心IT资产处置(ITAD)行业市场供需与战略研究报告
  8. python 打印类型_让Python输出更漂亮:PrettyPrinter
  9. 软件工程师安德烈·梅萨加冕 2021 世界小姐冠军
  10. 谁说Python慢来着?不用Python,这个问题难倒了无数的程序员