JobPlus知识库 IT 软件开发 文章
iOS开发中一些"有挑战"的问题

问题1: navigation push时隐藏的Tarbar怎么又回来了

问题描述

模拟类似Present的效果, 实现的思路如下

通过自定义Presented ViewController进入动画, 然后切换window的rootViewController到Presented ViewController

但是这种方式(先不谈论这种方式的方式是否合理和规范)会导致已隐藏的tabbar又显示出来的问题

问题发生在这样的条件下

  • 原先的rootViewController是一个UITabBarController

  • 每个Tab的子ViewController是NavigationController

  • push一个ViewController到NavigationController, 并且"hidesBottomBarWhenPushed = YES"

  • 切换rootViewController到Presented ViewController, 然后再切换回之前的UITabBarController

问题分析

在rootViewController是UITabBarController的情况下, push ViewController到NavigationController时, 配置"hidesBottomBarWhenPushed = YES"用来隐藏Tabbar

但是此时隐藏Tabbar的配置并不是存储在push的ViewController里, 而是与push动作相关联(这段是我的推测, 并没有源码做论证)

所以将rootViewController切换回之前的UITabBarController后, Tabbar就又显示出来了

问题解决

其实这个问题与刚开始的实现思路有关系, 这种模拟Present效果的方式并不常见, 所以必要性有待商榷, 但是这样也算是暴露出了一个iOS UI开发的问题

解决的思路是延续Apple的方式, 即push一个空的ViewController, 再pop出来, 这样Tabbar就与push动作又发生了关联, 由此Tabbar就又被隐藏了起来

问题2: 莫名消失的MBProgressHUD

问题描述

在点击Actionsheet的选项后, 弹出一个覆盖全屏的spinner(spinner使用的是第三库MBProgressHUD, 添加到keyWindow上), 同时ActionSheet也自动隐藏起来(因为点击选项了)

但是spinner弹出之后, 又立马迅速地消失了, 而如果再次弹出Actionsheet时, spinner又会随着Actionsheet一起显示出来

问题分析

从现象来看, 其实spinner并没有销毁, 而只是隐藏了起来, 否则不会随着Actionsheet第二次弹出而弹出

问题代码的实现是这样的


加载spinner到keywindow是在Actionsheet的clickedButtonAtIndex delegate里, 所以事件的时序是这样的

加载spinner到keywindow -> 隐藏Actionsheet

由于Actionsheet也是加载到底层的window上, 所以先前显示的spinner可能会随着Actionsheet的隐藏而隐藏起来了

问题解决

为了避免Actionsheet隐藏时带来的干扰, 我们希望事件的时序是这样的

隐藏Actionsheet -> 加载spinner到keywindow

很简单, 只需要用新的Actionsheet的delegate方法didDismissWithButtonIndex来替代clickedButtonAtIndex

里使用了第三方库DAContextMenuTableViewController

但是在使用shouldDisableUserInteractionWhileEditing选
项后, 侧滑cell后不能响应事件

并且此问题只出现在iOS7版本中, 而iOS8+系统并不存在该问题

问题分析


不能响应事件, 说明事件被拦截了, 即在要响应事件的view上层有其他view, 而这个其他view拦截了事件

通过打印UITableView的subViews, 发现确实存在这样的中间view

UITableView(1级)

----UITableViewWrapperView(2级)

--------UITableViewCell(3级)

--------UITableViewCell(3级)

----UIView(2级)

----UIImageView(2级)

UITableView是肯定能响应事件的, 而UITableViewCell并没有接收到事件, 那很可能是UITableViewWrapperView将事件拦截了

查看DAContextMenuTableViewController源码发现这里确实有问题


打印发现在iOS7系统中UITableViewWrapperView的view.gestureRecognizers.count=0

而在iOS8+系统中UITableViewWrapperView的view.gestureRecognizers.count>0

所以在iOS7中UITableViewWrapperView的userInteractionEnabled=NO, 所以事件就被UITableViewWrapperView拦截了而没有传递到cell

究其原因, 是不同iOS版本的内部实现差异导致的, 同时, 这种依赖于Apple平台的第三方库也要需要随着iOS的更新而更新

问题解决

条件语句不使用view.gestureRecognizers.count, 而是通过其subViews类型来判断当前view是否是UITableViewWrapperView



如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

¥ 打赏支持
40人赞 举报
分享到
用户评价(0)

暂无评价,你也可以发布评价哦:)

扫码APP

扫描使用APP

扫码使用

扫描使用小程序