Skip to content

4.3.0

Compare
Choose a tag to compare
@MoLice MoLice released this 30 Aug 21:34
· 50 commits to master since this release

新增功能

  1. QMUICommonDefines.h 增加宏 QMUIAssert 用于代替 NSAssert,作用是当业务使用 QMUIConsole 且打开了配置表 ShouldPrintQMUIWarnLogToConsole 时,该 assert 会把信息显示到 QMUIConsole 面板里,而不会触发 NSAssert,从而避免中断程序的运行。但如果业务项目没打开 ShouldPrintQMUIWarnLogToConsole,则该宏等价于 NSAssert
  2. UIViewController(QMUI) 增加 qmui_isSystemContainerViewController 方法(共两个,一个是类方法,一个是实例方法)用于判断当前的 viewController 是否为系统自带的 Container View Controller(例如 UINavigationControllerUITabBarController)。
  3. QMUIGridView 增加 padding 属性用于设置内部的间距。
  4. QMUIKeyboardManager 增加 isFloatingKeyboard 属性用于判断当前是否为 iPad 上的浮动键盘。
  5. QMUIPopupMenuBaseItemQMUIPopupMenuButtonItemheight 属性支持赋值为 QMUIViewSelfSizingHeight,以使每一行的高度自动根据当前行的内容来计算。在此之前该高度仅支持写死的固定值。
  6. QMUISearchController 增加 initWithContentsViewController:resultsTableViewStyle: 方法用于指定搜索结果列表的 style。
  7. QMUISearchController 增加 dimmingColor 用于设置搜索框聚焦键盘升起时的遮罩颜色。
  8. QMUIWeakObjectContainer 增加 isQMUIWeakObjectContainer 用于判断当前对象是否为 QMUIWeakObjectContainer,同时修复 QMUI 里若干用到这个类的地方判断写法不正确的问题(虽然写法不正确,但由于内部会做消息转发,所以不会引起实质性问题)。
  9. QMUIHelper 增加 canUpdateAppearance 属性用于判断当前是否可以设置 UIAppearance,该方法主要用于解决 #1281,具体请查看下方专项说明。
  10. QMUIHelper 增加 topMarginForAttributedImage:attributes: 可以根据图片大小、图片所在的富文本样式,计算得出一个能让图片在当前富文本里垂直居中的顶部偏移值。
  11. 新增 UIApplication(QMUI) 分类,提供 qmui_didFinishLaunching 属性用于判断当前 App 是否已完全启动。
  12. NSAttributedString(QMUI) 增加 qmui_attributedStringWithImage:alignByAttributes: 方法用于把 UIImage 转为 NSAttributedString 并利用参数的属性来自动调整 image 的垂直位置。
  13. NSAttributedString(QMUI) 增加 qmui_attributedStringWithImage:margins: 用于把 UIImage 转为 NSAttributedString 并利用参数调整 image 的上下左右布局偏移。
  14. NSString(QMUI) 增加 qmui_stringMatchedByPattern:groupIndex:qmui_stringMatchedByPattern:groupName: 方法支持使用正则表达式匹配字符串后返回指定分组的结果。
  15. UIButton(QMUI) 增加 qmui_setImageTintColor:forState: 方法用于便捷地给不同状态的 image 设置不同颜色。
  16. UIControl(QMUI) 增加 qmui_setSelectedBlock:qmui_setEnabledBlock: 便于在 selected、enabled 发生变化时做一些事情。
  17. 增加 UIFontMediumMakeUIFontMediumWithFontUIDynamicFontMediumMakeUIDynamicFontMediumMakeWithLimit 宏,以及 -[UIFont(QMUI) qmui_mediumSystemFontOfSize:] 方法用于生成 Medium 字重的字体。
  18. UIImage(QMUI) 增加 qmui_imageWithGradientColors:type:locations:size:cornerRadiusArray: 方法用于生成一张渐变图片。
  19. UILabel(QMUI) 增加属性 qmui_showPrincipalLines 可以显示当前文字的 descender、xHeight、capHeight、lineHeight,便于调试。
  20. UITextField(QMUI).qmui_selectedRange 属性从 readonly 改为 readwrite,方便业务通过 NSRange 形式去修改选中的区域,不用人工做一次类型转换。
  21. UITextView(QMUI) 增加 qmui_selectedRange 便于获取 NSRange 类型的选中区域。
  22. UIView(QMUI) 增加 qmui_fixedSize 属性用于简单地把某个 view 设置为固定大小,通常使用的场景是某个网络上加载下来的图片(大小不确定)要放在某个 UIButton 上,并且希望不管什么图都固定显示为某个 size,以前通常只有两种方式来实现:一是将图片裁剪为指定大小,二是重写一个自定义的 UIButton,现在可以简单地设置 UIButton.imageView.qmui_fixedSize 即可。
  23. UIView(QMUIBorder) 增加 qmui_borderInsets 用于调整边框的偏移值,具体效果可查看 QMUI Demo 里的 UIView+QMUI 示例。

会带来 QMUI 新旧版本兼容问题的更新

  1. #1231 #1284 近期若干个 App 提交 App Store 时会被拒绝,提示“The app references non-public selectors in Frameworks/QMUIKit.framework/QMUIKit: navigationBarBackgroundImage, navigationBarStyle, navigationBarTintColor”,但大部分 App 没收到这个提醒。其中提到的几个方法均为 QMUI 开天辟地时就存在的方法命名,之前一直没问题,暂不清楚原因。目前只能将其重命名,增加 qmui_ 前缀以避免审查。
  2. 废弃 QMUILinkButton,该组件的能力完全可以用新版的 UIView(QMUIBorder) 代替。
  3. 废弃 QMUIVisualEffectView,该组件的能力完全可以用 UIVisualEffectView(QMUI) 代替。但须注意这两者有细微的色差——系统的 UIVisualEffectView 内部由“磨砂+半透明前景色”组成,而 QMUIVisualEffectView 的实现方式是在系统基础上再叠加一个前景色,也即“磨砂+系统前景色+QMUI 前景色”,但 UIVisualEffectView.qmui_foregroundColor 是把系统自带前景色去掉后再叠加一层前景色,也即“磨砂+QMUI 前景色”,从而能更精准控制磨砂的样式。但更换为新版后,业务的磨砂效果应该会变得更明显,需要业务自行检查是否要重新调整 foregroundColor
  4. 删除配置表 SwitchTintColor 开关,这个开关仅在 iOS 12 及以前才有效,作用是在 UISwitch 关闭时显示外圈的颜色,一般没什么用,就不再提供了。
  5. -[NSAttributedString(QMUI) qmui_attributedStringWithImage:baselineOffset:leftMargin:rightMargin:] 标记为已废弃,且很快会在后续版本删除,请尽快使用新增的 qmui_attributedStringWithImage:margins: 代替。
  6. 删除 QMUICustomizeButtonPropType 及关联的 qmui_hasCustomizedButtonPropForState:qmui_hasCustomizedButtonPropWithType:forState: 方法,忘了当初为什么加这些东西了。
  7. UILabel(QMUI).qmui_lineHeight 属性原本只是简单地设置文字的 lineHeight,但由于 iOS 的特性,不管 lineHeight 设置为多少,文字都是居底部对齐,但市面上基本所有的设计软件(如 figma、sketch),以及其他平台的布局代码,默认都是文字在行高内垂直居中,这容易导致布局还原效果差,需要反复调整,因此这版本里 qmui_lineHeight 默认会使文字垂直居中,项目里原本使用该属性的地方,更新版本后间距可能会变化,需要业务项目检查。经过衡量,我们认为长远来看该更新成本是值得的。

如何适配新版

  1. 以 Matching Word 形式全局 Replace QMUINavigationControllerAppearanceDelegate 里的7个方法,加上“qmui_”前缀。
  2. Matching Word 形式全局搜索“QMUILinkButton”,将用到的地方改为 QMUIButton + UIView.qmui_borderPosition 代替。例如:
    // QMUILinkButton *linkButton = QMUILinkButton.new;
    QMUIButton *linkButton = QMUIButton.new;
    linkButton.qmui_borderPosition = QMUIViewBorderPositionBottom;
    linkButton.qmui_borderColor = linkButton.currentTitleColor;
    linkButton.qmui_borderWidth = 1;// QMUILinkButton 之前默认的下划线大小为1pt
  3. Matching Word 形式全局搜索“QMUIVisualEffectView”,将用到的地方改为 UIVisualEffect.qmui_foregroundColor,并检查其效果是否符合业务的需求。
  4. 全局搜索用到 -[NSAttributedString(QMUI) qmui_attributedStringWithImage:baselineOffset:leftMargin:rightMargin:] 的地方,将其改为新方法 -[NSAttributedString(QMUI) qmui_attributedStringWithImage:margins:]
  5. 全局搜索 “QMUICustomizeButtonPropType”、qmui_hasCustomizedButtonPropForState:qmui_hasCustomizedButtonPropWithType:forState:,如果有用到,请将相关的 QMUI 旧代码复制为业务代码使用。
  6. 全局搜索用到“qmui_lineHeight”的地方,查看该地方的布局是否有问题(更新 QMUI 后布局应该会比之前偏上)。
  7. 如果有使用配置表,请删除其中的“SwitchTintColor”相关代码。

Bugfix

  1. #1152 #1159 #1227 #1278 重新优化“Main Thread Checker: UI API called on a background thread: -[UIWindow traitCollection]”的问题。
  2. #1180 修复没有使用 QMUINavigationController 的情况下,执行 pop 操作时可能依然还在上一次转场动画过程中,此次的 pop 会被系统忽略,导致命中 UINavigationController (QMUI) 里的 NSAssert 的问题。
  3. #1232 修复 UISearchBar(QMUI).qmui_alwaysEnableCancelButton 可能出现 crash 的 bug。
  4. 修复 UISearchBar(QMUI) 在没有设置 qmui_cancelButtonMarginsBlock 的情况下 qmuisb_shouldFixLayoutWhenUsedAsTableHeaderView 无效的 bug。
  5. #1243 [UIKit Bug] 修复 iOS 11 及以上,关闭 estimated height 的 tableView 可能出现数据错乱引发 crash 的 bug。
  6. #1246 修复 QMUIButton.highlightedBackgroundColor 没有兼容 qmui_maskedCorners 的 bug。
  7. #1253 修复配置表 AutomaticCustomNavigationBarTransitionStyleYES 的效果在 pop 时可能出错的 bug。
  8. #1257 #1263 修复在非全面屏的 Regular 设备里,仅支持竖屏的 App 在横屏启动时界面错乱的 bug。
  9. #1258 修复 QMUITextView 在使用 placeholder 的情况下调用 sizeToFit 会出现 NaN 的 bug。
  10. #1281 [UIKit Bug] 修复 App 处于后台时修改 UIAppearance 里 UIImage 类型的属性很大几率导致第三方键盘 crash 的 bug。——该 bug 很重要,在下文专项说明
  11. #1282 修复 QMUITextField 通过代码 setText: 修改文字后,光标无法正确置于文字末尾的 bug。
  12. #1283 修复 -[UIButton(QMUI) qmui_setTitleAttributes:forState:] 在 iOS 12 及以下系统无效的 bug。
  13. #1286 [UIKit Bug] 修复使用 UITabBarAppearanceUITabBarItem 选中时的字体设置为 bold 则无法完整显示 title 的 bug。
  14. 重构 -[UIButton(QMUI) qmui_setTitleAttributes:forState:] 方法,修复其他 state 下无法设置 title 的 bug。
  15. 修复 -[QMUIButton sizeThatFits] 在参数为 CGSizeZero 时错误返回了高度为 0 的大小(系统 UIButton 在这种情况下会返回真实内容大小)。
  16. 修复 QMUIMultipleDelegatesRAC 冲突导致死循环的 bug。
  17. 修复 QMUISearchController 在 iPad 分屏时用 QMUIEmptyView 显示空结果的情况下,改变分屏的比例,QMUIEmptyView 的宽度没有刷新的 bug。
  18. 修复 QMUITextView 设置了 textAlignmentRightplaceholder 样式没同步的 bug。
  19. 修复 QMUIThemeImage 在使用 resizableImageWithCapInsets:resizableImageWithCapInsets:resizingMode: 后无法保持其动态特性的 bug。
  20. 修复 iOS 10-11,QMUITheme 动态颜色在 UILabel.textColor 上无法及时刷新的 bug。
  21. 修复 QMUITheme 里处理 keyboardAppearance 的逻辑会对 UITextField 内部的 UIFieldEditor 也生效的 bug。
  22. 修复关闭 theme 主题跟随系统的开关后,切换 App 里的 Light/Dark theme,UITabBarbackgroundEffect 值刷新但样式没刷新的 bug。
  23. 修复 UITraitCollection(QMUI) 里没有对 window 过滤 nil 导致 App 从桌面唤醒时可能无法立即显示正确的 style 的 bug。
  24. 修复 UIView(QMUIBorder) 在不显示 border 时依然会触发多次不必要的 setNeedsLayout 的 bug。
  25. 修复 QMUIKeyboardManager 在某些情况下键盘 hide 过程中还会触发 show 的 bug。

其他

  1. QMUIAlertController 内部的 titleLabelmessageLabel 类型从 UILabel 改为 QMUILabel 以支持长按复制。
  2. 将分类 NSMutableParagraphStyle(QMUI) 改为 NSParagraphStyle(QMUI) 以支持更多类型。
  3. 监听 UIGestureRecognizer 执行过程中是否被禁用(典型案例是试图在 viewWillAppear: 里禁用当前界面的手势返回,这样会导致从当前界面的下一个界面手势返回时界面卡死)。
  4. UINavigationController(QMUI) 增加对 pushViewController:setViewControllers: 的保护,避免重复 push 触发系统的 crash。
  5. 优化 UIVisualEffectView(QMUI).qmui_foregroundColor,当开启系统的“降低透明度”辅助功能开关后, 屏蔽它的半透明效果,避免出现怪异表现。

关于 #1281 的特别说明

近期我们意识到在使用 QMUI 的 App 里,第三方键盘很容易被系统杀掉重启,经过一番测试,证实确实与 QMUI 有关,但问题的根源在于系统的 UIAppearance 协议在某些场景下的使用会导致内存暴涨,而 QMUI 刚好命中了这些场景。具体的分析解释请查看 #1281 (comment) ,建议必读。
总结来说,使用 QMUI 的项目要规避这个问题,不能仅依靠 QMUI 自己的更新,业务项目也需要同步配合进行以下几个措施:

  1. 更新最新版的 QMUI(4.3.0 及后续版本)。
  2. 配置表里 UIImageUIColor 的属性,都用一个全局变量存起来,目的是为了保证切换 theme 时不会重新赋值(指针相同就不会执行 setter)。
  3. 搜索项目业务代码,确保在 theme 变化时会设置的 UIAppearance 逻辑,用 if (QMUIHelper.canUpdateAppearance) 的判断包起来。

做完以上举措后,可以用最新版 QMUI Demo 验证效果(内置 Keyboard Extension)。

  1. 在你的模拟器/真机上运行 QMUI Demo,此时设置里会出现新键盘“QMUIKeyboard-QMUI(Debug)”,将其添加为唯一的输入法。
  2. 打开你的 App,点击某个输入框以升起 QMUI 键盘,可看到键盘上显示了一个数字。
  3. 保持键盘显示的状态,不断重复“回到桌面-打开App-回到桌面”,观察键盘上的数字是否稳定“每次增加固定值”,例如以 QMUI Demo 为例,每次都会增加5。

如果测试结果符合第3点,该数字没有指数型上升,就意味着你的业务项目是正常的,可以放心使用。