awesome-tips
  • 简介
  • 语言
    • Objective-C
      • 1. 覆盖父类同名属性
      • 2. 不支持 __weak 修饰的类
      • 3. 一个命名引发的崩溃
      • 4. 再谈数组、集合、字典与 hash、isEqual 方法的关联
      • 5. Objective-C import 第三方库头文件总结
      • 6. 如何对 NSMutableArray 进行 KVO
      • 7. 如何重写自定义对象的 hash 方法
      • 8. 你的遍历方法用对 @autoreleasepool 了么
      • 9. Objective-C 可变容器对象的初始化方法使用总结
      • 10. iOS9之后字符串变换API
      • 11. 弱持有容器方案
      • 12. 缓存 NSDateFormatter
      • 13. Objective-C中自定义泛型类
      • 14. Objective-C 泛型的协变与逆变
      • 15. iOS 金额字符串格式化显示的方法
      • 16. 换一种 Hook 的姿势
    • Swift
      • 1. 使用 CaseIterable 获取枚举的所有 case
      • 2. Swift 4.x 中使用 +load 和 +initialize
      • 3. Swift 4.2 MemoryLayout 新方法 offset(of:)
    • C/C++/Clang
      • 1. 宏中的 ## 的含义
      • 2. 如何正确使用初始化方法的标记宏
      • 3. 开源库使用的 Clang __attributes__
      • 4. __builtin_expect 简介
  • 多线程
    • 1. 定时器引发的思考
    • 2. 另一种形式定时器
    • 3. 再谈 timer 之 CFRunLoopTimerRef
    • 4. 利用 GCD 信号量将异步方法改造为同步方法
    • 5. 几个第三方框架关于线程锁的封装小技巧
    • 6. 一个关于 GCD 分组任务的小 tip
    • 7. 判断是否在主队列运行
    • 8. 说说 NSTimer 的新 API
  • Xcode
    • 1. 使用 Named UIColor
    • 2. Xcode 10 / iOS 12 获取 WiFi 信息
    • 3. Xcode 工程添加 “动态” Framework 的几种方式
    • 4. Xcode 的 Build Settings 选中 Levels 时不同列的含义
    • 5. 关于 Assets 中图片的 Slicing 功能
    • 6. Xcode 调试技巧之 attach to process by PID or name
    • 7. 关于 Xcode Archive 后 App 出现在 Other Items 分组里的解决办法
    • 8. 配置 xcodebuild 命令打包支持 Bitcode
    • 9. Xcode 断点调试时打印变量值报错的问题(编译优化相关)
    • 10. 推荐几个高频使用的 Xcode 小技巧
    • 11. Xcode 设置代码只在 Debug 下起效的几种方式
    • 12. Extract Function/Extract Method
    • 13. Fix All issue
    • 14. Xcode 9 中快速定位目标控制器
    • 15. 关于 Xcode console 输出的 UIImage 警告的解决方式
    • 16. 使用 Toolchains 在 Xcode 中切换 Swift 版本
    • 17. 打包时 Xcode 无法及时更新 Provisioning Profile 的解决办法
    • 18. 解决修改 xcconfig 配置版本号和 build 号不生效的问题
    • 19. 解决Xcode真机无法联调的野路子
    • 20. Assets的几个方便用法
  • UI
    • 1. 为 UIView “截屏”
    • 2. 如何使 UIImagePickerController 支持横屏
    • 3. Safe Area 的一些零散点
    • 4. Storyboard 中的约束优先级
    • 5. UIWindow 的显示特性与常见操作方法小结
    • 6. 屏幕底部边缘系统手势与按钮点击冲突
    • 7. UITabController tabBarItem 的图片显示异常
    • 8. 提高开发效率 --- UI 部分
    • 9. iPhone 屏幕分辨率终极指南
    • 10. IBDesignable + IBInspectable 实时更新 UI
    • 11. UITableView & UICollectionView 设置单元格的默认选中状态
    • 12. 一个由曝光统计引起的对 tableView 估计高度的探究
    • 13. 利用 Storyboard Reference 给 storyboard 瘦身
    • 14. 你还在使用占位 View 吗?
    • 15. 如何快速定位哪个 View 出现了约束警告?
    • 16. 聊聊 AutoLayout 的一对属性
    • 17. 自定义 cell 时,[self addSubView] 和 [self.contenView addSubView] 的区别
    • 18. 给 UIView 添加阴影
    • 19. 通过 runtime 控制导航栏的 hidden 属性
    • 20. 静态 UITableView 两种 style 的差异
    • 21. UIAlertView 与输入框结合使用时的一个坑
    • 22. 延时动画的两种方式对比
    • 23. iOS 处理 navigationBar.titleTextAttributes 属性时机
    • 24. 如何定制一个 UIView 类型控件的出入动画
    • 25. UIView 的事件透传
    • 26. 再谈 iOS 输入框的字数统计/最大长度限制
    • 27. 被大家忽略的UIViewController两对API
    • 28. UIScrollView 拖拽滑动时收起键盘
    • 29. 再谈 UITableView 的 estimatedRowHeight
    • 30. 水平可者竖直布局方案
    • 31. 为icon换装
    • 32. 如何优雅地获取 ScrollView 的滚动方向
    • 33. 三个打印类信息的私有方法
    • 34. 对渐变视图的实现方案的探究
  • Webview
    • 1. iOS12 设置 WKWebView 的 UserAgent
    • 2. WKWebView 使用 WKWebViewJavascriptBridge 需要注意的地方
    • 3. 解决 WKWebview 滚动后白屏问题
    • 4. 研究 WKWebview 的子 view 和 html body 的关系
    • 5. iOS 如何调试 WebView
    • 6. iOS 如何调试 WebView (二)
    • 7. Webview关闭时手动停止音频播放
    • 8. 让失去焦点的 UIWebView 弹出键盘的方法
    • 9. 解决 WKWebView 无法处理 URL Scheme 和 App Store 链接的问题
    • 10. JSON 格式化显示
  • 音视频
    • 1. 使用 AVCaptureSession 踩的一个坑
    • 2. 为什么音频播放器突然没声音了呢?
    • 3. iOS 中音量控制解惑
    • 4. iOS 关于音频播放调研
    • 5. 使用 Audio Queue 进行流式录音
    • 6. 替换系统音量提示
  • 优化
    • 1. iOS 内存泄露工具
    • 2. 一些 UI 性能优化的 tips
    • 3. 两种 App 启动连续闪退检测策略
    • 4. WWDC 2018 苹果推荐的大图加载方式
    • 5. 删除iOS项目中未使用的图片
    • 6. 使用 YYFPSLabel 快速检测页面滑动的流畅度
    • 7. iOS App 启动时间测量
    • 8. iOS 中的 GZIP 压缩
    • 9. 为 Fabric MOD 一个卡顿检测功能
    • 10. CGDataProviderCreateWithData 的内存管理
    • 11. 比较三种网络框架上传图片过程中的不同点?
    • 12. 怎么解决网络请求的依赖关系
    • 13. 对 App Store 在蜂窝网 150MB 的下载限制的理解
    • 14. 一次内存泄漏后的思考
    • 15. iOS 自带九宫格拼音键盘与 Emoji 表情之间的坑
    • 16. NSFetchedResultsController 的另一个坑
  • 调试
    • 1. 提高Shortcuts调试效率的小技巧
    • 2. 是谁调了我的底层库
    • 3. Quick Look Debugging
    • 4. 在 Cycript 和 LLDB 中使用私有的方法调试 iOS
    • 5. 使用 LLDB bugreport 命令导出 App 运行崩溃日志
    • 6. 使用 LLDB expression 命令调试动态更新 UI
    • 7. Cycript调试第三方APP
    • 8. 断案高手之otool
  • 工程
    • 1. 利用 Git-hook 自动配置不同仓库的用户信息
    • 2. 应用 icon 被 Cocoapods “吃掉”的解决方式
    • 3. Pod 关于 unknown UUID 警告的解决方式
    • 4. Diff:/Podfile.lock NO such file or directory
    • 5. 对于“静态库”和“动态库”的理解总结
    • 6. C++ 库不兼容问题处理
    • 7. iOS 运行时代码注入工具 Injection
    • 8. Swift 版本建私有库时需要注意的地方
    • 9. 你的项目中还用热修复吗?
    • 10. iOS快速解析崩溃日志
    • 11. TestFlight 删除测试人员血泪史
    • 12. 模块化带来的痛之模块之间的数据同步
    • 13. podspec 中预编译宏的使用
    • 14. 查看.a静态库中的.o文件及函数接口信息
  • 安全/越狱
    • 1. 谈一谈iOS平台跨域访问漏洞
    • 2. “偷窥”第三方APP头文件
    • 3. iOS App 的反调试(Anti-Debug)
    • 4. 使用 Keychain 存储登录态需要注意的一个坑
  • 其它
    • 1. 一入 IAP 深似海
    • 2. 一入 IAP 深似海第二弹
    • 3. 关于 IAP 丢单的处理
    • 4. SecRandomCopyBytes 生成伪随机数
    • 5. 忘记AppleID账号安全问题的解决办法
    • 6. 句子拆分
    • 7. 关于定位的一个小知识点
    • 8. iOS 获取设备型号最新总结
    • 9. iOS App “去评分” 功能的几种实现总结
    • 10. NSLog 遇到的问题
    • 11. 简单区分 SDWebImage 的三种缓存
    • 12. 关于 NSDate 中夏令时的坑
    • 13. 简单了解 iOS 大小端以及转换
    • 14. 获取 ipa 包三种姿势
    • 15. iOS中的mach_continuous_time()方法
    • 16. 查找未国际化的文字
    • 17. 一个结构较为合理的下载模块该怎么设计
    • 18. RACObserve 常见用法及区别
    • 19. CoreData 关系的4种删除规则
    • 20. CoreData 检索遇到的坑及其解决方式
    • 21. 我们可以利用 NSURLProtocol 做什么
    • 22. iOS 11 后还使用旧方法获取设备剩余空间?
    • 23. iOS 9 以后通知不再需要手动移除
    • 24. 使用 Apple Configuration 配置自动加入 Wi-Fi
    • 25. iOS9 以后 openURL 和 canOpenURL 使用限制的小误区
Powered by GitBook
On this page
  • UIWindow 的显示特性
  • UIWindow常见操作方法总结

Was this helpful?

  1. UI

5. UIWindow 的显示特性与常见操作方法小结

作者:陈满iOS

UIWindow 的显示特性

1、相同 windowLevel 下,调整 UIWindow 显示层的基本方法

1) 显示相关属性:hidden

  • 如果仅仅想显示一个UIWindow

customWindow.hidden = NO;

虽然设置自己的 hidden 即可显示出来,但上述方法并不会"自动"影响之前显示的 UIWindow 对象的 hidden 属性。如果,之前 UIWindow 的 hidden = NO,设置新 UIWindow 的 hidden 将旧 UIWindow 覆盖后,旧 UIWindow 的 hidden 属性依旧为 NO。

  • 如果仅仅想隐藏一个 UIWindow

customWindow.hidden = YES;

如果你没有专门设置过 hidden 属性,系统默认为 YES。上述代码会将 UIWindow 绝对隐藏,不管有没其他 UIWindow 覆盖。当也没有其它非隐藏的 UIWindow 的时候,APP 屏幕完全黑屏。

  • 如果想显示一个UIWindow,同时设置为keyWindow,并将其显示在同一windowLevel的其它任何UIWindow之上

- (void)makeKeyAndVisible

上述方法真的会将其显示在同一windowLevel的其它任何UIWindow之上!显示最上层的UIWindow以最后执行过该代码的UIWindow为准。

2) 显示相关方法:makeKeyAndVisible 的作用

[self.window makeKeyAndVisible];

其执行效果包括 但不限于 执行了如下代码(因为还会覆盖同 level 的所有 window):

[self.window makeKeyWindow];
self.window.hidden = NO;

讲真,makeKeyAndVisible 真的会自动改变 hidden 属性值为 NO。

3) UIWindow 对象的 hidden 属性默认值

  • 默认值:true

如果你仅仅创建一个 UIWindow,而又不专门设置 hidden 属性(或者makeKeyAndVisible),系统默认分配的默认值为true。

4) 误区:关于 keyWindow 的混淆易错点

设置 keyWindow 与否并不影响视图层级显示,仅来接收键盘及其它非触摸事件。如果没有专门设置过 keyWindow 的 hiden 为 NO,而且也没有其它非隐藏的 UIWindow,那么APP会黑屏。

  • 如果仅仅设置为keyWindow

- (void)makeKeyWindow
  • 如果仅仅解除为keyWindow

- (void)resignKeyWindow

app 的 keyWindow 与是否在最上层显示没有任何关系。比如,你如果想通过 [[UIApplication sharedApplication] keyWindow] 获取正在显示的 UIWindow 是极其不准确 的。有时候通过这个代码获取的如果真的是正在显示的 UIWindow,仅仅是因为碰巧而已。

5) 警惕点:有多个 hidden 属性 =NO 的 UIWindow,该显示谁?

如上所见,makeKeyAndVisible 与 hidden 的 setter 方法均可以改变 hidden 的值,但有个问题,经过多次调整,可能有多个 UIWindow 的 hidden 都为 NO,那么应该显示谁?

  • 对于 hidden 的 setter 方法,最终显示的以最后执行过 .hidden=NO 的 UIWindow 为准,且执行 .hidden=NO 之前 hidden 的值为 YES。(hidden如果是从NO改为NO的不 算 最后 改变UIWindow的显示状态)

  • 对于 makeKeyAndVisible 方法,最终显示的以最后 执行过 makeKeyAndVisible 的 UIWindow 为准。

  • 对于先后分别用 makeKeyAndVisible 方法和 hidden 的 setter 方法,还是先后分别用 hidden 的 setter 方法和 makeKeyAndVisible 方法,结局同样以最后改变显示状态的 UIWindow 为准。

2、基于 windowLevel,调整 UIWindow 显示层的拓展方法

先去 UIWindow.h 里面看看 UIWindowLevel 的定义:

例如,在手势相关类中调整自定义的 UIWindow 层级

[self.window makeKeyAndVisible]; 
_window.windowLevel = UIWindowLevelAlert;
  • 打印代表 UIWindowLevelAlert 层级的数据值

(lldb) po self.window.windowLevel
2000
  • 同理,打印代表UIWindowLevelStatusBar层级的数据值

(lldb) po self.window.windowLevel
1000
  • 同理,打印代表UIWindowLevelNormal层级的数据值

(lldb) po self.window.windowLevel
0

小结:

  1. windowLevel 数值越大的显示在窗口栈的越上面

  2. 显示层的优先级 为: UIWindowLevelAlert > UIWindowLevelStatusBar > UIWindowLevelNormal

  3. 系统给 UIWindow 默认的 windowLevel 为UIWindowLevelNormal

UIWindow常见操作方法总结

1、获取 App 所有 window 的 windows 数组

[[UIApplication sharedApplication] windows]

例如,第三方加载动画框架 KVNProcess 中 KVNProgress.m 文件会有一段这样的代码,如下图1所示

2、keyWindow

[[UIApplication sharedApplication] keyWindow]

例如,第三方下拉菜单框架 FFDropDownMenu 的 FFDropDownMenuView.m 文件中有这样一段代码:

UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
[keyWindow addSubview:self];

这段代码的目的是添加到最上层 UIWindow,但实际操作是把自己的视图添加到 keyWindow 上。其实,如果我们在编写代码时严谨地保证 keyWindow 是显示在最上层的 UIWindow,这样写没有问题。但如果:自己或者其它第三方框架曾经调高过其它 UIWindow 属性 windowLevel,或者有同级 windowLevel 的其它 UIWindow 后来改变过显示状态(如 .hidden=NO,makeKeyAndVisible 等),可能会导致下拉菜单的弹出视图无法显示(被覆盖)。

3、获取 AppDelegate 单例的 window 属性 专门获取 AppDelegate.m 文件中的 window 属性,不包含其它其定义的 window

[[[UIApplication sharedApplication] delegate] window]
Previous4. Storyboard 中的约束优先级Next6. 屏幕底部边缘系统手势与按钮点击冲突

Last updated 6 years ago

Was this helpful?