QMUI IOS Versions Save

QMUI iOS——致力于提高项目 UI 开发效率的解决方案

4.3.0

2 years ago

新增功能

  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 刚好命中了这些场景。具体的分析解释请查看 https://github.com/Tencent/QMUI_iOS/issues/1281#issuecomment-894678981 ,建议必读。 总结来说,使用 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点,该数字没有指数型上升,就意味着你的业务项目是正常的,可以放心使用。

4.2.3

3 years ago

新增功能

  1. 增加 UICollectionView(QMUI) 提供 qmui_selectedBackgroundColor 属性便于设置点击时的背景色,同时也更便于兼容 QMUITheme
  2. QMUIEmotionView 增加 verticalAlignment 等若干属性以支持类似微信的竖向滚动交互。
  3. QMUIButton 增加属性 cornerRadius 用于更方便地设置按钮圆角,同时提供常量 QMUIButtonCornerRadiusAdjustsBounds 使其可以维持圆角为按钮高度的一半,不用业务自己在按钮大小发生变化时更新圆角值。
  4. UIColor(QMUI) 增加方法 qmui_distanceBetweenColor: 用于计算两个颜色之间的相近程度,原理是将两个颜色转换为 HSB 模型后取两点之间的距离,注意该方法会忽略 alpha 通道。
  5. UISearchBar(QMUI) 增加属性 qmui_searchController 用于获取与当前 searchBar 绑定的 UISearchController 对象。
  6. UISearchBar(QMUI) 增加属性 qmui_alwaysEnableCancelButton 支持当某个 searchBar 脱离 UISearchController 存在时,强制使其 cancelButton 一直处于 enabled 状态(系统默认在输入框聚焦时 enabled,失焦时 disabled,这通常不是我们想要的)。
  7. UITabBar(QMUI) 增加属性 qmui_effectView 用于获取内部的磨砂 view。
  8. UITabBar(QMUI) 增加属性 qmui_effect 支持直接修改 tabBar 的磨砂类型(系统仅在 iOS 13 及以后才支持)。
  9. UITabBar(QMUI) 增加属性 qmui_effectForegroundColor 支持精准指定 tabBar 磨砂的前景色,系统默认是无法做到这一点的,因为 UIVisualEffectView 在某些 blur style 下会有自带的一层前景色,且无法修改,你设置的前景色最终会和系统的前景色叠加,导致总是无法精准实现业务所需效果。
  10. UITableView(QMUI) 增加属性 qmui_indexFrame 用于获取 tableView 右边那条 sectionIndex 索引条的 frame
  11. UITableViewCell(QMUI) 增加属性 qmui_didAddToTableViewBlock 便于在 cell 能拿到 tableView 引用的第一时间做一些事情,例如根据不同 style 的 tableView 作不一样的样式区分。
  12. UITableViewCell(QMUI) 增加属性 qmui_configureStyleBlock 让 cell 层面也能得到 willDisplayCell 的渲染时机,在这个 block 里你可以拿到 tableView 的引用,也可以知道当前 cell 的 indexPathqmui_cellPosition 等信息,便于你做一些全局样式的管理。
  13. -[UIImage imageWithTintColor:]-[UIImage qmui_imageWithTintColor:] 支持将静态 image 和动态 color 组合为动态 image,在此之前你需要手动创建一个动态 image,在 provider block 里根据动态 color 的不同值生成不同的 image。

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

  1. 由于 QMUIButton 增加的 cornerRadius 圆角接口,原本在子类 QMUIFillButtonQMUIGhostButton 里自行实现的 cornerRadius 均被去除,对应的常量 QMUIFillButtonCornerRadiusAdjustsBoundsQMUIGhostButtonCornerRadiusAdjustsBounds 也一并删除。
  2. 将上个版本被标记为已废弃的 +[QMUIThemeManager sharedInstance] 方法彻底删除。
  3. #1193 由于修复 UIViewController.qmui_tabBarSpacingInViewCoordinator未考虑 hidesBottomBarWhenPushed = YES 的情况的 bug,所以以前某个 vc 如果 hidesBottomBarWhenPushed = YES,但却利用 qmui_tabBarSpacingInViewCoordinator 去获取布局信息,那么在新版本更新后,这个 vc 里拿到的值将为 0。0 是正确的,因为此时 tabBar 不可见,但却可能导致业务界面产生与 QMUI 4.2.2 不同的表现。
  4. #1219 QMUINavigationControllerTransitionDelegate 里提供的接口 navigationController:poppingByInteractiveGestureRecognizer:viewControllerWillDisappear:viewControllerWillAppear: 无法直观判断手势返回最终是成功了还是取消了,因此新版本为其增加了新参数 isCancelled,同时将旧方法标记为废弃,建议尽快替换为新方法。
  5. 由于设计师的回归,这个版本 QMUI Demo 调整了默认的 logo、配色,理论上不应该对业务项目产生任何影响(因为 QMUI Demo 是一个独立的示例项目),但保险起见,在 Release Note 里明确写出。

如何适配新版

  1. 全局搜索“QMUIFillButtonCornerRadiusAdjustsBounds”、“QMUIGhostButtonCornerRadiusAdjustsBounds”,将其换成新的 QMUIButtonCornerRadiusAdjustsBounds
  2. 全局搜索使用 +[QMUIThemeManager sharedInstance] 的地方,将其删除,并考虑用 QMUIThemeManagerCenter.defaultThemeManager 代替。
  3. 全局搜索用到 qmui_tabBarSpacingInViewCoordinator 的地方,检查该界面是否 hidesBottomBarWhenPushed = YES 且非 UINavigationControllerrootViewController,如果存在该情况,请注意它的布局是否正常。
  4. 全局搜索用到 navigationController:poppingByInteractiveGestureRecognizer:viewControllerWillDisappear:viewControllerWillAppear: 的地方,为其增加参数 isCancelled,具体参数的位置请查看 QMUI 源码。

Bugfix

  1. #999 修复 QMUITextView 在输入过程中从一行换到两行时会产生的跳动问题,同时修复 QMUITextView 初始化后通过代码设置 text,后续手动聚焦输入文字瞬间会跳动的 bug。
  2. #1161 [UIKit Bug] 修复将 UISearchBar 作为 tableHeaderView 使用的 UITableView,如果同时设置了 estimatedRowHeight,则 contentSize 会错乱,导致滚动异常的系统 bug。
  3. #1176 修复在 MainThreadChecker 开启的状态下使用了 QMUITheme 后可能导致“directTraitCollectionIMP EXC_BAD_ACCESS”的 bug。
  4. #1177 修复 iOS 14.0-14.2,setViewControllers: 去到一个 hidesBottomBarWhenPushed = NO 的界面会 crash 的 bug。
  5. #1180 修复 UINavigationController 不可见的情况下进行 pop 操作会命中 UINavigationController+QMUI.m 内的 NSAssert 的问题,同时借机优化 #261 里 -[UINavigationController pushViewController:animated:]isViewControllerTransiting 的使用逻辑。
  6. #1181 修复 QMUITextView 在显示 placeholdersizeThatFits: 返回的结果没有包含 placeholder 占位大小的 bug。
  7. #1187 修复 -[UITabBarItem(QMUI) qmui_imageViewInTabBarButton:] 方法在打开了系统的“辅助功能-显示与文字大小-按钮形状”后无法获取到正确 imageView 的 bug。
  8. #1190 修复 iOS 12 及以下,在 rootViewController、以 animated:NO 进行的 push/pop 界面,- [QMUINavigationControllerDelegate titleViewTintColor] 无效的 bug。
  9. #1192 修复 - [QMUIMultipleDelegates respondsToSelector:] 不支持 NSProxy 类型的 delegate 成员的 bug。
  10. #1198 修复 +[QMUIHelper isRegularScreen] 对 iPhone 12/12 Pro 判断错误,导致横屏时获取导航栏高度错误的 bug。
  11. #1200 修复 QMUIConsole 在子线程里输出 log 会 crash 的 bug。
  12. #1207 [UIKit Bug] 修复将 UISearchBar 作为 UITableView.tableHeaderView 使用时,如果列表内容不满一屏,可能出现搜索框不可视的系统 bug。
  13. #1210 修复 - [QMUINavigationControllerDelegate titleViewTintColor] 在 iOS 12 下手势返回又取消后可能出错的 bug。
  14. #1213 [UIKit Bug] 修复 UISearchBar 作为 tableHeaderView 使用时,切换 tableView 的 sectionIndex 的显隐,searchBar 的布局可能无法刷新的系统 bug。
  15. #1215 [UIKit Bug] 修复将 UISearchBar 作为 tableHeaderView 使用的 UITableView,在 tableView 尚未添加到 window 上就同时进行了 setTableHeaderView:reloadData 的操作,会导致滚动异常的系统 bug。
  16. #1216 修复 iOS 12 及以下,QMUITableViewStyleInsetGrouped 在编辑、排序状态下布局错误的 bug。
  17. #1217 [UIKit Bug] 修复 iOS 12 及以上的系统,如果设置了自己的 leftBarButtonItem,且 title 很长时,则当 pop 的时候,title 会瞬间跳到左边,与 leftBarButtonItem 重叠的系统 bug。
  18. #1218 修复 UITabBarItem.selectedImage 无法二次更新的 bug。
  19. 修复高帧率设备下 QMUIDisplayLinkAnimation 动画时长减半的 bug。
  20. 修复 QMUINavigationBarScrollingAnimatorbarTintColorBlock 属性无效的 bug。
  21. 修复 NSString(QMUI) 提供的 qmui_substringAvoidBreakingUpCharacterSequencesFromIndex:lessValue:countingNonASCIICharacterAsTwo:qmui_substringAvoidBreakingUpCharacterSequencesToIndex:lessValue:countingNonASCIICharacterAsTwo: 这两个方法里当参数 countingNonASCIICharacterAsTwoYES 时,没有将参数 index 按照 countingNonASCIICharacterAsTwo 的规则来计算的 bug。
  22. 修复 UITableView(QMUI).qmui_validContentWidth 属性在列表出现右边的 sectionIndex 索引条时返回的宽度错误的 bug。

其他

  1. #1166 QMUIConsole 的实现从 textView 改为 tableView,以优化在展示大量 log 时的性能,同时也优化了搜索的关键词高亮体验。
  2. #1220 优化 QMUI 内的 valueForKey: 用法可能存在一些风险。
  3. #1214 @0x1306a94 兼容未启用 CLANG_ENABLE_MODULES 时通过 CocoaPods 集成会产生的编译错误。
  4. 配置表 NavBar 系列属性发生变化时会去刷新当前界面的 navigationBar,如果该界面有通过 QMUINavigationControllerDelegate 提供的统一接口去自定义业务界面自己的样式,则配置表不需要强制帮它刷新。

4.2.2

3 years ago

新增功能

  1. UINavigationController (QMUI) 增加方法 qmui_didInitialize 方便子类重写 init 时的逻辑,因为系统的 UINavigationController 总共有4个 NS_DESIGNATED_INITIALIZER,子类每次都重写这4个方法成本过高也容易遗漏。
  2. UINavigationController (QMUI) 增加 QMUINavigationAction 枚举用于标志当前 navigationController 的导航动作状态,并提供对应的 qmui_navigationAction qmui_addNavigationActionDidChangeBlock: 方法便于在某些导航动作产生时做一些事情,免去每个地方自己 hook/override 一遍 setViewControllers、pushViewController、popViewController、popToViewController、... 的麻烦(且 pop 操作有多种,容易遗漏)。
  3. - [QMUINavigationControllerAppearanceDelegate titleViewTintColor] 接口现在对系统的 title 也可以生效(以前仅对 QMUINavigationTitleView 才生效)。
  4. 增加 UINavigationItem (QMUI),提供多个接口方便访问关联的 navigationBar、navigationController 等信息。
  5. UIViewController (QMUI) 增加 qmui_isDescendantOfViewController: 用于判断当前 vc 是否为指定 vc 本身,或者是其 childViewController、childViewController 的 childViewController、...。
  6. QMUIHelper 增加系列接口对应新发布的 iPhone 设备:
    1. is67InchScreen
    2. is61InchScreenAndiPhone12
    3. is54InchScreen
    4. screenSizeFor67Inch
    5. screenSizeFor61InchAndiPhone12
    6. screenSizeFor54Inch
  7. #1146 @ZenonHuang QMUIHelper 更新 deviceName 以兼容新发布的设备。
  8. QMUIHelper 增加方法 isMac、QMUICommonDefines.h 增加宏 IS_MAC 用于区分是否 Mac Catalyst App 或 iOS 项目直接在 M1 设备上运行的情况。
  9. QMUICommonDefines.h 增加宏 PreferredValueForInterfaceIdiom(_phone, _pad) 用于区分 phone、pad 两种情况,注意当 iPad 分屏时,如果 App 窗体宽度较窄,也会被视为 phone。
  10. QMUIRuntime.h 增加 qmui_exists_dyld_image 函数用于检测是否存在某个 dyld image。
  11. UITextField (QMUI) 增加方法 qmui_convertNSRangeFromUITextRange:qmui_convertUITextRangeFromNSRange: 便于类型转换。
  12. - [QMUIModalPresentationViewControllerDelegate shouldHideModalPresentationViewController:] 现在支持所有显示类型了,之前仅对 window 方式有效。
  13. #1142 QMUIOrderedDictionary 增加 allValues 属性。
  14. #1108 #1113 配置表增加 NavBarContainerClasses 用于限定 NavigationBar 系列开关的生效范围,增加 TabBarContainerClasses 用于限定 TabBar 系列开关的生效范围,增加 ToolBarContainerClasses 用于限定 Toolbar 系列开关的生效范围,从而避免配置表的样式影响系统界面(例如从业务 App 里打开的相册、通讯录、打印等系统界面)。
  15. 配置表增加 TabBarItemTitleFontSelected 用于设置选中状态的 UITabBarItem 的字体。

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

  1. -[QMUINavigationController didInitialize] 被标记为废弃,将会在后续版本中被移除,请尽快将其替换为 qmui_didInitialize
  2. 废弃配置表的 ShouldFixTabBarButtonBugForAll,改为强制自动修复 #410 描述的系统 bug,因为这种 bug 正常情况下没有“不希望被修复”的诉求。
  3. 修正 CALayer (QMUIViewAnimation). qmui_viewAnimationEnabled 拼写错误的问题。
  4. 将若干类方法的定义改为类属性(@property (class)),便于访问。
  5. 删除 - [UITabBarItem (QMUIConfiguration) qmui_updateTintColorForiOS12AndEarlier:] 方法。

如何适配新版

  1. 检查项目里继承自 QMUINavigationController 的所有子类是否有实现 didInitialize 方法,有的话请将其替换为 qmui_didInitialize
  2. 全局搜索“qmui_viewAnimaitonEnabled”,将其替换为“qmui_viewAnimationEnabled”。
  3. 全局搜索“qmui_updateTintColorForiOS12AndEarlier”,清理用到的地方。
  4. 如果你是 Swift 项目,类方法改为类属性可能会导致你的语法需要从 QMUIHelper.deviceName() 替换为 QMUIHelper.deviceName,由于数量众多,请遇到报错时自行修改。

如果有使用配置表

  1. 删除配置表的 ShouldFixTabBarButtonBugForAll 项。
  2. 将以下代码添加到配置表中并修改为希望的值:
    QMUICMI.navBarContainerClasses = nil; // NavBarContainerClasses : NavigationBar 系列开关被用于 UIAppearance 时的生效范围(默认情况下除了用于 UIAppearance 外,还用于实现了 QMUINavigationControllerAppearanceDelegate 的 UIViewController),默认为 nil。当赋值为 nil 或者空数组时等效于 @[UINavigationController.class],也即对所有 UINavigationBar 生效,包括系统的通讯录(ContactsUI.framework)、打印等。当值不为空时,获取 UINavigationBar 的 appearance 请使用 UINavigationBar.qmui_appearanceConfigured 方法代替系统的 UINavigationBar.appearance。请保证这个配置项先于其他任意 NavBar 配置项执行。
    QMUICMI.tabBarContainerClasses = nil; // TabBarContainerClasses : TabBar 系列开关的生效范围,默认为 nil,当赋值为 nil 或者空数组时等效于 @[UITabBarController.class],也即对所有 UITabBar 生效。当值不为空时,获取 UITabBar 的 appearance 请使用 UITabBar.qmui_appearanceConfigured 方法代替系统的 UITabBar.appearance。请保证这个配置项先于其他任意 TabBar 配置项执行。
    QMUICMI.toolBarContainerClasses = nil; // ToolBarContainerClasses : ToolBar 系列开关的生效范围,默认为 nil,当赋值为 nil 或者空数组时等效于 @[UINavigationController.class],也即对所有 UIToolbar 生效。当值不为空时,获取 UIToolbar 的 appearance 请使用 UIToolbar.qmui_appearanceConfigured 方法代替系统的 UIToolbar.appearance。请保证这个配置项先于其他任意 ToolBar 配置项执行。
    QMUICMI.tabBarItemTitleFontSelected = nil; // TabBarItemTitleFontSelected : 选中的 UITabBarItem 的标题字体
    

Bugfix

  1. 修复 +[QMUIHelper safeAreaInsetsForDeviceWithNotch] 不准确的 bug。
  2. 修复 StatusBarHeightConstant 宏不准确的 bug。
  3. 修复 QMUICommonViewController 内置的 QMUINavigationTitleView 无法响应 UIViewController.navigationItem.title 的值的 bug。
  4. 修复 dismiss 到一个正在搜索的界面时,状态栏无法正确交给 UISearchController,而是错误地交给 searchController 背后的 vc 的 bug。
  5. 修复开启了配置表 NeedsBackBarButtonItemTitle 的情况下,业务自己设置的 UIViewController.navigationItem.backBarButtonItem 会被强制覆盖的 bug。
  6. 修复 iOS 12 及以下的系统,通过 [UITabBarItem setTitleTextAttributes:forState:] 设置的 selected 字体无法生效的系统 bug(颜色可以生效,字体不行)。
  7. 修复开启了转场动画过程中 navigationBar 效果优化功能后,在转场动画过程中前后界面的样式发生变化,此时无法正确更新假 bar 的问题。
  8. #1087 修复使用了 QMUITheme 后,在 iOS 14 下首次升起键盘会触发 Main Thread Checker 警告的问题,4.2.1 里只是优化,4.2.2 里彻底修复。
  9. #1115 修复 QMUI 某些 description 可能触发 Main Thread Checker 的 bug。
  10. #1120 修复 QMUITextView 点击候选词触发最长字符数限制时,高度变化的回调 newHeightAfterTextChanged 不会调用的 bug。
  11. #1122 修复 QMUITheme 在切换主题时无法刷新 UITabBarItem.selectedImage 的 bug。
  12. #1130 修复配置表 NeedsBackBarButtonItemTitlebackBarButtonItemTitleWithPreviousViewController: 与系统的 backBarButtonItem 三者互相冲突的问题。
  13. #1148 修复 - [QMUIEmptyView sizeThatContentViewFits:] 高度计算错误的 bug。
  14. #1149 修复 QMUIZoomImageView 在 image/livePhoto/videoPlayerItem 三种内容之间切换时没有清空其他内容,导致缩放错误的 bug。
  15. #1150 修复 QMUIModalPresentationViewController hide 时没有正确清空 keyboardHeight 的 bug。
  16. #1156 修复 QMUICommonTableViewController 搭配 Storyboard 使用时 crash 的问题。
  17. #1163 修复 QMUIPieProgressView 使用约束布局时圆角有误的 bug。
  18. #1168 #1170 修复 QMUITextFieldQMUITextView 设置了 maximumTextLength 后,在配合系统的三指粘贴/撤销快捷操作时可能引发 crash 的 bug。
  19. #1169 修复 iPad 12-inch 上一旦出现了 QMUIConsole,界面上其他元素就无法点击的 bug。
  20. #1173 修复 QMUIKeyboardManager 无法兼容系统的“设置→辅助功能→动态效果→减弱动态效果→首选交叉淡出过渡效果”的问题。

其他

  1. 优化配置表 PreventConcurrentNavigationControllerTransitions 功能,在切换界面时如果上一次转场动画尚未结束,以前直接屏蔽本次切换,现改为将本次切换的 animated 置为 NO,既能避免 bug,又能允许界面正常切换。
  2. 优化 UIView (QMUI)UIImageView (QMUI) 内部若干 hook,将 hook 时机从 +load 改为按需。
  3. #1100 iOS 14.2 开始,系统已经修复了该问题,因此 QMUI 新版本里对 iOS 14.2 及以后的版本都屏蔽了相关代码。

4.2.1

3 years ago

新增功能

  1. QMUISearchController 支持通过 qmui_preferredStatusBarStyleBlock 控制进入搜索状态时的状态栏样式,不需要再在 QMUISearchControllerDelegate 里记录、刷新状态栏了。
  2. UISearchBar(QMUI) 增加属性 qmui_textFieldMarginsBlock 支持根据不同的 active 状态设置不同的输入框 margin。
  3. UISearchBar(QMUI) 增加属性 qmui_cancelButtonMarginsBlock 支持调整取消按钮 margin。
  4. #1106 QMUICustomNavigationBarTransitionDelegate 增加方法 shouldCustomizeNavigationBarTransitionIfUsingCustomTransitionForOperation:fromViewController:toViewController: 用于控制当业务实现了自己的转场动画时,是否还需要开启 QMUI 的 navigationBar 转场优化。旧版本在业务实现了自己的转场动画时,必定无法使用 navigationBar 转场优化。
  5. QMUIHelper 增加 +layerContentsGravityWithContentMode: 用于 UIViewContentModeCALayerContentsGravity 之间的转换。
  6. UIControl(QMUI) 增加属性 qmui_preventsRepeatedTouchUpInsideEvent 用于防止快速的重复点击。业务可以 swizzle UIControl 的 init,在里面统一开启某些指定控件的防重复点击(例如 QMUI Demo 默认开启了 UINavigationBar 上的按钮的防重复点击)。

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

  1. 删除 QMUIUserInterfaceStyleWillChangeNotification,改为用 +[UITraitCollection qmui_addUserInterfaceStyleWillChangeObserver:selector:] 监听系统的 Dark Mode 切换,从而优化 #1087 (#1045 #1059 #1080) 提的 iOS 14 下首次升起键盘时会命中 Main Thread Checker 警告的问题,优化后只有用了 QMUITheme 组件的才会命中警告(原理上无法避免,仅对开发过程有影响,不影响发布版 App)。
  2. 配置表 StatusbarStyleLightInitially 开关以前只能对 QMUICommnoViewController 及其子类生效,现在对 QMUITabBarViewControllerQMUINavigationController 的所有 childViewController 都可以生效,不管该 childViewController 父类是什么。
  3. UIImageView(QMUI).qmui_smoothAnimation 的默认值从 YES 改为 NO,因为实测目前系统在 UIScrollView 里用 UIImageView 展示 GIF 已经没有什么性能问题。
  4. 去掉代码里所有的 #ifdef IOS13_SDK_ALLOWED 判断。

如何适配新版

  1. 全局搜索“QMUIUserInterfaceStyleWillChangeNotification”,将其改为用新的 +[UITraitCollection qmui_addUserInterfaceStyleWillChangeObserver:selector:]
  2. 检查在 QMUITabBarViewControllerQMUINavigationController 里展示的非 QMUICommonViewController 子类的 viewController 的状态显示是否正常。
  3. 检查业务项目里使用 qmui_smoothAnimation 展示 GIF 的场景是否还正常。
  4. 请勿使用低于 Xcode 11 的版本进行开发。

如果有使用配置表

Bugfix

  1. #888 修复 -[QMUITableViewCell layoutSubviews] 里对 textLabel 布局的手误写法。
  2. #809 #898 修复设置了 overrideUserInterfaceStyle 后启动 App 会死循环的 bug。
  3. #983 修复 QMUIModalPresentationViewController 在调用 show 后无法立马通过 hide 隐藏浮层的 bug。
  4. #1065 修复 QMUIPieProgressView 绘制环形时报警告“CGContextClosePath: no current point.” 的 bug。
  5. #1066 修复 QMUINavigationTitleView subAccessoryView 布局错误的 bug。
  6. #1071 修复 UIImageView(QMUI).qmui_smoothAnimation = YES 时修改 contentMode 无效的 bug。
  7. #1073 修复 CALayer(QMUI).qmui_maskedCorners 无法对独立的 CALayer 生效,只能作用于 UIView.layer 的问题。
  8. #1074 修复 CALayer(QMUI).qmui_maskedCorners 无法在子线程中使用,会触发 UIView layoutSublayersOfLayer: 导致命中 NSAssert 的问题。
  9. #1079 去掉 UIView(QMUI) 内对 convertRect 系列的坐标系检测,去掉 addSubview: 对“把 self add 到 self 上”的检测。
  10. #1081 #1107 修复 iOS 14 开启 customNavigationBarTransitionKey 的情况下转场效果错误,bar 透明的 bug。
  11. #1090 修复单独 pod QMUIImagePickerLibrary 无法正确拿到 QMUIResources 图片的 bug。
  12. #1094 修复某些场景下 UINavigationController(QMUI).qmui_isPushing 可能遇到数组越界的 bug。
  13. #1096 修复 QMUIBadge 可能出现未读数字宽度小于高度的 bug。
  14. #1100 修复 iOS 14 pop 到一个 hidesBottomBarWhenPushed = NO 的界面后 UITabBar 无法正确显示出来的系统 bug。
  15. #1105 修复 QMUITextView 粘贴文字时如果受到 maximumTextLength 限制时无法自动裁剪的 bug。
  16. #1110 修复 iOS 14 修改 UITabBarAppearance.inlineLayoutAppearance.normal.titleTextAttributes[NSForegroundColorAttributeName] 会导致 UITabBarItem 文字无法完整展示的 bug。
  17. 修复 QMUINavigationController 里对状态栏样式管理的 bug。
  18. 修复开启 BoldText 后同时显示文字+图片的 QMUIButton 文字无法完整展示的 bug。
  19. 修复 +[UIImage(QMUI) qmui_animatedImageWithData:scale:] 在传入的 data 只有一张图的情况下无法通过参数 scale 指定图片倍数的 bug。
  20. 修复 -[UINavigationController(QMUI) qmui_pushViewController:animated:completion:] 系列方法的 completion 实际上会立马被调用的 bug。
  21. 修复 QMUICommonTableViewController description 里的循环调用。

其他

  1. #1091 使用二分查找法优化查找 view 所在 section 的过程 by @MaxwellLeeee 。
  2. QMUIThemeImage 里的消息转发兼容 OpenCV
  3. 移除 +[QMUIHelper executeAnimationBlock:completionBlock:] 注释里对支持 UINavigationController 转场动画的说明。
  4. 优化 QMUIKit 若干在 +load 里的 method swizzling,改为在用到相应功能时才进行 swizzle。

4.2.0

3 years ago

由于 iOS 14 Beta 的发布,QMUI 从这个版本开始将不再支持 iOS 9

新增功能

  1. 增加 QMUITableViewStyleInsetGrouped 组件用于支持全 iOS 版本的 InsetGrouped 类型的列表,示例代码请查看 QMUI Demo→QMUIKit→QMUITableView→QMUITableViewStyleInsetGrouped。
  2. 配置表增加 TableViewGroupedSeparatorColor 用于控制 UITableViewStyleGrouped 类型的列表分隔线颜色。
  3. #1015 QMUIAlertController 增加 alertTextFieldTextInsetsalertTextFieldMarginBlock 属性用于调整输入框的大小和布局。
  4. QMUIPopupContainerView 增加 arrowImage 属性支持用一张图来作为浮层的箭头。
  5. QMUIStaticTableViewCellData 增加 didSelectBlock,支持以 block 的形式处理 cell 点击事件(以前只能使用 target-action 模式);增加 accessoryBlock,支持以 block 的形式处理 accessoryView 点击事件(以前只能使用 target-action 模式)。
  6. UIColor(QMUI) 增加 qmui_colorWithRGBAString: 方法用于将一个 RGBA 字符串转换成 UIColor 对象。
  7. UIView(QMUI) 增加 qmui_sizeThatFitsBlock 属性便于重写 sizeThatFits:
  8. 增加 UIVisualEffectView(QMUI) 组件,提供 qmui_foregroundColor 属性让你可以去掉系统自带的前景色的同时设置自己的前景色,从而保证更准确的设计效果。系统的 UIVisualEffectView 在不同的 style 下会带有不同的前景色。
  9. UITableView(QMUI) 增加 qmui_validContentWidth 属性用于获取当前列表用于呈现内容的区域的宽度,例如全面屏设备下会减去 safeAreaInsets.left/right,InsetGrouped 样式下会减去左右的缩进。
  10. UITableViewCell(QMUI) 增加以下特性:
    1. 增加 qmui_style 属性用于获取初始化 cell 时指定的 UITableViewCellStyle
    2. 增加 qmui_cellPosition 属性用于在 willDisplayCell 及以后的时机里能获取当前 cell 在 section 里的位置,如果是在 cellForRow 里则依然只能自己通过 -[UITableView qmui_positionForRowAtIndexPath:] 计算,无法使用 qmui_cellPosition
    3. 增加 qmui_separatorInsetsBlockqmui_topSeparatorInsetsBlock 用于控制 cell 的分隔线位置,由于 block 是渲染时才会调用,所以你可以在 block 里方便地根据当前 tableView 的 style、cell 的 position、cell 的 subviews 的布局来设置分隔线位置,这是系统自带的分隔线无法做到的事情。你可以在业务项目里 swizzle UITableViewCell 的 init 方法,在里面统一设置全局分隔线的逻辑,就无需每个 cell 子类都调整一次。
  11. UISearchBar(QMUI) 增加以下特性,对应地 QMUI Demo 也增加新的示例界面:QMUIKit→UISearchBar+QMUI→UISearchBar(QMUI)
    1. 增加 qmui_centerPlaceholder 用于让 iOS 11 及以后的搜索框 placeholder 也能默认居中(系统默认是居左)。
    2. 增加 qmui_leftAccessoryViewqmui_rightAccessoryView 支持在输入框左右各显示一个 view,从而你可以方便地添加自己的按钮(例如在搜索框左边显示一个返回按钮,在右边显示一个结果过滤、结果排序按钮等)。
  12. QMUIHelper 增加 executeBlock: oncePerIdentifier: 用于令某段逻辑只被执行一次,QMUIKit 中通常用来避免重复 swizzle 相同方法。
  13. QMUICommonDefines.h 增加 IOS14_SDK_ALLOWED 用于识别当前是 iOS 14 SDK 编译环境。
  14. UINavigationBarUITabBar 在没设置 backgroundImage 时也能正确显示 shadowImage(系统默认行为是只有设置了 backgroundImageshadowImage 才能生效),从而保证不同 iOS 系统里的表现一致。
  15. 感谢 @MaxwellLeeee 增加对 QMUIToastAnimator 里 Zoom 和 Slide 两种动画方式的支持。

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

  1. 最低支持版本从 iOS 9.0 升级为 iOS 10.0。
  2. 重构 QMUIBadge 未读数组件,原本仅支持在 UIBarItem 上显示未读数/未读红点,现在可以在任意的 UIView 上显示未读数/未读红点了。同时为了优化使用体验,将原本基于中心布局的 qmui_badgeCenterOffsetqmui_badgeCenterOffsetLandscapeqmui_updatesIndicatorCenterOffsetqmui_updatesIndicatorCenterOffsetLandscape 4个属性标记为废弃,新组件将基于右上角布局,使用新属性 qmui_badgeOffsetqmui_badgeOffsetLandscapeqmui_updatesIndicatorOffsetqmui_updatesIndicatorOffsetLandscape 代替以前的4个旧属性。同时 QMUI Demo 里也增加了对应的示例代码。
  3. 对于 UITableView,如果开启了配置表并且将 TableViewEstimatedHeightEnabled 置为 NO,则在 4.2.0 里会在初始化时把 tableView.rowHeight 修改为 TableViewCellNormalHeight,而在 4.2.0 以前,不管是否使用配置表,不管 TableViewEstimatedHeightEnabled 的值多少,在 tableView 初始化时 rowHeight 会保持系统默认(UITableViewAutomaticDimension)。这可能会让使用了 self-sizing 的 UITableView cell 高度错误,无法自动计算。遇到这种情况,请考虑将配置表里的 TableViewCellNormalHeight 改为 UITableViewAutomaticDimension,或者仅修改出问题的业务界面的 tableView.rowHeight = UITableViewAutomaticDimension;

如何适配新版

  1. 全局搜索“qmui_badgeCenterOffset”,改为用 qmui_badgeOffset,具体值要自行调整。
  2. 全局搜索“qmui_badgeCenterOffsetLandscape”,改为用 qmui_badgeOffsetLandscape,具体值要自行调整。
  3. 全局搜索“qmui_updatesIndicatorCenterOffset”,改为用 qmui_updatesIndicatorOffset,具体值要自行调整。
  4. 全局搜索“qmui_updatesIndicatorCenterOffsetLandscape”,改为用 qmui_updatesIndicatorOffsetLandscape,具体值要自行调整。
  5. 全局搜索“BadgeCenterOffset”,改为用 BadgeOffset
  6. 全局搜索“BadgeCenterOffsetLandscape”,改为用 BadgeOffsetLandscape
  7. 全局搜索“UpdatesIndicatorCenterOffset”,改为用 UpdatesIndicatorOffset
  8. 全局搜索“UpdatesIndicatorCenterOffsetLandscape”,改为用 UpdatesIndicatorOffsetLandscape
  9. 全局搜索对 QMUIAlertController.dismissKeyboardAutomatically 的使用,由于不支持 iOS 9,所以这个属性已经没用了,请删除。

如果有使用配置表

  1. 将以下代码添加到配置表里:
QMUICMI.badgeOffset = CGPointMake(-9, 11); // BadgeOffset : QMUIBadge 上的未读数相对于目标 view 右上角的偏移
QMUICMI.badgeOffsetLandscape = CGPointMake(-9, 6); // BadgeOffsetLandscape : QMUIBadge 上的未读数在横屏下相对于目标 view 右上角的偏移
QMUICMI.updatesIndicatorOffset = CGPointMake(4, UpdatesIndicatorSize.height); // UpdatesIndicatorOffset : QMUIBadge 未读红点相对于目标 view 右上角的偏移
QMUICMI.updatesIndicatorOffsetLandscape = UpdatesIndicatorOffset; // UpdatesIndicatorOffsetLandscape : QMUIBadge 未读红点在横屏下相对于目标 view 右上角的偏移

QMUICMI.tableViewGroupedSeparatorColor = TableViewSeparatorColor; // TableViewGroupedSeparatorColor : Grouped 类型的 QMUITableView 分隔线颜色

#pragma mark - InsetGrouped TableView
QMUICMI.tableViewInsetGroupedCornerRadius = 10; // TableViewInsetGroupedCornerRadius : InsetGrouped 类型的 UITableView 内 cell 的圆角值
QMUICMI.tableViewInsetGroupedHorizontalInset = PreferredValueForVisualDevice(20, 15); // TableViewInsetGroupedHorizontalInset: InsetGrouped 类型的 UITableView 内的左右缩进值
QMUICMI.tableViewInsetGroupedBackgroundColor = TableViewGroupedBackgroundColor; // TableViewInsetGroupedBackgroundColor : InsetGrouped 类型的 UITableView 的背景色
QMUICMI.tableViewInsetGroupedSeparatorColor = TableViewGroupedSeparatorColor; // TableViewInsetGroupedSeparatorColor : InsetGrouped 类型的 QMUITableView 分隔线颜色
QMUICMI.tableViewInsetGroupedCellTitleLabelColor = TableViewGroupedCellTitleLabelColor; // TableViewInsetGroupedCellTitleLabelColor : InsetGrouped 类型的 QMUITableView cell 里的标题颜色
QMUICMI.tableViewInsetGroupedCellDetailLabelColor = TableViewGroupedCellDetailLabelColor; // TableViewInsetGroupedCellDetailLabelColor : InsetGrouped 类型的 QMUITableView cell 里的副标题颜色
QMUICMI.tableViewInsetGroupedCellBackgroundColor = TableViewGroupedCellBackgroundColor; // TableViewInsetGroupedCellBackgroundColor : InsetGrouped 类型的 QMUITableView cell 背景色
QMUICMI.tableViewInsetGroupedCellSelectedBackgroundColor = TableViewGroupedCellSelectedBackgroundColor; // TableViewInsetGroupedCellSelectedBackgroundColor : InsetGrouped 类型的 QMUITableView cell 点击时的背景色
QMUICMI.tableViewInsetGroupedCellWarningBackgroundColor = TableViewGroupedCellWarningBackgroundColor; // TableViewInsetGroupedCellWarningBackgroundColor : InsetGrouped 类型的 QMUITableView cell 在提醒状态下的背景色
QMUICMI.tableViewInsetGroupedSectionHeaderFont = TableViewGroupedSectionHeaderFont; // TableViewInsetGroupedSectionHeaderFont : InsetGrouped 类型的 QMUITableView sectionHeader 里的文字字体
QMUICMI.tableViewInsetGroupedSectionFooterFont = TableViewInsetGroupedSectionHeaderFont; // TableViewInsetGroupedSectionFooterFont : InsetGrouped 类型的 QMUITableView sectionFooter 里的文字字体
QMUICMI.tableViewInsetGroupedSectionHeaderTextColor = TableViewGroupedSectionHeaderTextColor; // TableViewInsetGroupedSectionHeaderTextColor : InsetGrouped 类型的 QMUITableView sectionHeader 里的文字颜色
QMUICMI.tableViewInsetGroupedSectionFooterTextColor = TableViewInsetGroupedSectionHeaderTextColor; // TableViewInsetGroupedSectionFooterTextColor : InsetGrouped 类型的 QMUITableView sectionFooter 里的文字颜色
QMUICMI.tableViewInsetGroupedSectionHeaderAccessoryMargins = TableViewGroupedSectionHeaderAccessoryMargins; // TableViewInsetGroupedSectionHeaderAccessoryMargins : InsetGrouped 类型的 QMUITableView sectionHeader accessoryView 的间距
QMUICMI.tableViewInsetGroupedSectionFooterAccessoryMargins = TableViewInsetGroupedSectionHeaderAccessoryMargins; // TableViewInsetGroupedSectionFooterAccessoryMargins : InsetGrouped 类型的 QMUITableView sectionFooter accessoryView 的间距
QMUICMI.tableViewInsetGroupedSectionHeaderDefaultHeight = TableViewGroupedSectionHeaderDefaultHeight; // TableViewInsetGroupedSectionHeaderDefaultHeight : InsetGrouped 类型的 QMUITableView sectionHeader 的默认高度(也即没使用自定义的 sectionHeaderView 时的高度),注意如果不需要间距,请用 CGFLOAT_MIN
QMUICMI.tableViewInsetGroupedSectionFooterDefaultHeight = TableViewGroupedSectionFooterDefaultHeight; // TableViewInsetGroupedSectionFooterDefaultHeight : InsetGrouped 类型的 QMUITableView sectionFooter 的默认高度(也即没使用自定义的 sectionFooterView 时的高度),注意如果不需要间距,请用 CGFLOAT_MIN
QMUICMI.tableViewInsetGroupedSectionHeaderContentInset = TableViewGroupedSectionHeaderContentInset; // TableViewInsetGroupedSectionHeaderContentInset : InsetGrouped 类型的 QMUITableView sectionHeader 里的内容的 padding
QMUICMI.tableViewInsetGroupedSectionFooterContentInset = TableViewInsetGroupedSectionHeaderContentInset; // TableViewInsetGroupedSectionFooterContentInset : InsetGrouped 类型的 QMUITableView sectionFooter 里的内容的 padding
  1. 将以下设置项从配置表里删除:
QMUICMI.badgeCenterOffset = CGPointMake(14, -10); // BadgeCenterOffset : QMUIBadge 未读数相对于目标 view 中心的偏移
QMUICMI.badgeCenterOffsetLandscape = CGPointMake(16, -7); // BadgeCenterOffsetLandscape : QMUIBadge 未读数在横屏下相对于目标 view 中心的偏移
QMUICMI.updatesIndicatorCenterOffset = CGPointMake(14, -10); // UpdatesIndicatorCenterOffset : QMUIBadge 未读红点相对于目标 view 中心的偏移
QMUICMI.updatesIndicatorCenterOffsetLandscape = CGPointMake(14, -10); // UpdatesIndicatorCenterOffsetLandscape : QMUIBadge 未读红点在横屏下相对于目标 view 中心点的偏移

Bugfix

  1. #997 修复输入框聚焦并升起键盘的情况下,App 进入后台再回到前台,键盘外观会错误的 bug。
  2. #1001 修复在 Mac Catalyst 里调用 +[UIImage qmui_imageWithThemeProvider] 会死循环的 bug。
  3. #1012 修复 QMUIPopupMenuButtonItem 内的 QMUIButton.imageView 可能出现负值的 bounds,导致一些布局错误的 bug。
  4. #1026 修复 iOS 12 及以下,UITabBarItem 只设置 image 没设置 selectedImage 时,无法通过配置表设置图片颜色的 bug。
  5. #1037 修复 QMUIToast 修改内容后布局没有刷新的 bug。
  6. #1042 修复 iOS 14 下切换到 emoji 键盘会 crash 的 bug。
  7. #1048 修复 `-[QMUIZoomImageView showEmptyViewWithText] 无法显示 emptyView 的 bug。
  8. #1051 修复 QMUIButton 搭配 Autolayout 使用时可能出现的文字布局错误的 bug。
  9. #1061 修复 CocoaPods Spec 文件里对 Photos.framework 的依赖写法,改为在 Subspec 内依赖,避免引入其他子模块时也错误地引入了 Photos.framework。
  10. #1063 修复 iOS 14 下当关闭 NeedsBackBarButtonItemTitle 后,长按返回按钮出现的快速返回菜单里无法显示标题的 bug。
  11. 修复 iOS 14 下修改了 UISearchBar 字体后会导致 searchBar 内的输入框高度错误的 bug。
  12. 修复 iOS 12 及以下 UITextField(QMUI).qmui_clearButtonImage 无效的 bug。
  13. 修复 QMUINavigationTitlteView 在 vertical 布局模式下,如果 subtitle 比 title 长的话可以看到 loading 和 accessoryView 与 title 之间间距过大的 bug。
  14. 修复 QMUINavigationTitleView 文字长度过长时没有截断的 bug。
  15. 修复使用 QMUINavigationButton 作为自定义返回按钮时,在 iOS 13.4.1 系统新增的 Full Keyboard Access 模式下无法使用快捷键 Tab+B 返回上一级界面的 bug。
  16. 修复 QMUIAppearance 无法在非 UIViewUIViewController 对象里使用的 bug。
  17. 修复 -[UIImage (QMUI) qmui_imageWithTintColor:]opaqueimage 效果错误的 bug。
  18. 修复 +[QMUIHelper compareSystemVersion:toVersion:] 返回结果相反的 bug。
  19. 修复 NSString(QMUI)qmui_substringAvoidBreakingUpCharacterSequencesFromIndex:lessValue:countingNonASCIICharacterAsTwo:qmui_substringAvoidBreakingUpCharacterSequencesToIndex:lessValue:countingNonASCIICharacterAsTwo: 裁剪不准确的 bug。
  20. 修复以下几个类的类方法里初始化实例的错误写法,导致如果是子类通过类方法得到的依然是父类的实例的 bug。
    1. QMUIAlertAction
    2. QMUIDisplayLinkAnimation
    3. QMUILogItem
    4. QMUIConsoleLogItem
    5. QMUIEmotion
    6. QMUIMoreOperationItemView
    7. QMUIMultipleDelegates
    8. QMUIPopupMenuButtonItem
    9. QMUIStaticTableViewCellData
    10. QMUIPropertyDescriptor
    11. UIBarButtonItem(QMUINavigatiaonButton)
    12. UIColor(QMUITheme)
    13. NSMutableParagraphStyle(QMUI)

其他

  1. 将原本属于 UIControl(QMUI)qmui_outsideEdge 属性迁移到 UIView(QMUI),使其适用于更多场景。
  2. 优化 QMUIModalPresentationViewController 在键盘位置发生变化时刷新布局的频率。
  3. 优化 QMUICommonTableViewController 手势返回过程中当前 selected 的那个 cell 的背景色可以跟随手势进度慢慢消失。
  4. QMUICommonTableViewController 里原本监听 contentInset 的 KVO 主体改为一个独立的对象,避免 QMUICommonTableViewController 的子类重写 observeValueForKeyPath:ofObject:change:context: 时不知道要调用 super 的问题。
  5. 去掉 -[CALayer(QMUI) qmui_sendSublayerToBack:]-[CALayer(QMUI) qmui_bringSublayerToFront:] 里对参数是否属于当前 layer 的 sublayers 的判断,使这两个方法更通用。
  6. 感谢 @kimwjc 优化对 UIAccessibility 无障碍访问的支持。

4.1.3

4 years ago

新增功能

  1. 新增 CGFloatEqualToFloat()CGFloatEqualToFloatWithPrecision() 函数用于浮点数的等值比较。

Bugfix

  1. #978 修复 QMUIImagePickerPreviewViewController 的一些操作按钮无法点击的 bug。
  2. #980 #981 修复 4.1.2 的 ShouldFixTabBarSafeAreaInsetsBug 在某些情况下可能导致界面的各种 inset 错乱的 bug。

4.1.2

4 years ago

新增功能

  1. 新增 CALayer (QMUIViewAnimation),让 CALayer 可以在 +[UIView animateWithDuration:animations:] 内直接写动画代码。
  2. UIImage(QMUI) 增加属性 qmui_resizable 用于区分当前是否为 resize 处理过的图片。
  3. UINavigationBar(QMUI) 增加属性 qmui_contentView 用于获取导航栏内部的 contentView。
  4. UISearchBar(QMUI) 增加属性 qmui_fixMaskViewLayoutBugAutomatically 用于控制是否要自动修复 #950 的系统 bug,默认不修复。
  5. +[QMUIHelper deviceName] 补齐新发布的设备。

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

  1. 以更彻底的方式修复系统在某些场景下 UITabBar 的布局 bug,同时修改了配置表 ShouldFixTabBarSafeAreaInsetsBugForNotchedScreen 的命名,具体适配操作请查看如何适配新版
  2. 之前某些组件为了方便,在 init 时就用 loadViewIfNeeded 触发 viewDidLoad 来初始化 subviews,然而这会导致继承了这些组件的子类写在 init 里的业务逻辑的调用时机比写在 viewDidLoad 里的调用时机还晚,可能引发一些非预期的问题,所以这个版本我们去掉了这种做法,理论上是无感知的改动,安全起见建议按 如何适配新版 进行检查。

如何适配新版

  1. 请检查项目里相关组件的使用是否正常,包括这些组件的子类的使用:
    1. QMUIAlertController
    2. QMUIImagePickerViewController
    3. QMUIImagePreviewViewController
    4. QMUIMoreOperationController
    5. QMUIConsoleViewController
  2. 如果有使用配置表,请搜索“shouldFixTabBarSafeAreaInsetsBugForNotchedScreen”,将其重命名为“ shouldFixTabBarSafeAreaInsetsBug”。
  3. 如果有使用配置表,请将以下代码添加到配置表并设置为希望的值:
QMUICMI.windowLevelQMUIConsole = 1; // UIWindowLevelQMUIConsole : QMUIConsole 内部的 UIWindow 的 windowLevel
QMUICMI.shouldFixSearchBarMaskViewLayoutBug = NO; // ShouldFixSearchBarMaskViewLayoutBug : 是否自动修复 UISearchController.searchBar 被当作 tableHeaderView 使用时可能出现的布局 bug(issue #950)

Bugfix

  1. #218 #934 以更彻底的方式修复系统 UITabBar 在若干情况下的各种布局 bug。
  2. #949 修复 QMUIPopupContainerView 在指定方向空间不足的情况下无法自动切换到反向显示 bug。
  3. #950 修复当 UISearchController.searchBar 作为 tableHeaderView 使用时,顶部可能出现 1px 的间隙导致露出背景色的系统 bug。
  4. #952 修复 shouldPopViewControllerByBackButtonOrPopGesture: 在某些情况下传入的参数错误的 bug。
  5. #968 修复 QMUIConsoleapplication:didFinishLaunchingWithOptions: 里 App 主 UIWindow 尚未显示前就调用时无法显示的 bug。
  6. #970 修复 QMUITextView 与 ReactiveObjC 搭配使用时会死循环的 bug。
  7. #971 修复 iOS 12 及以下版本,QMUIThemeImage 在搭配 resizable 使用的情况下可能无法跟随主题刷新的 bug。
  8. #974 修复 -[QMUICellHeightCache qmui_invalidateHeightForKey:] 无效的 bug。
  9. #975 修复 iOS 9 下 QMUIAlertController 无法显示的 bug。
  10. 修复 iOS 9 下调用 qmui_applyAppearance 会提前触发 viewDidLoad 的问题。
  11. 修复 QMUIModalPresentationViewControllershowInView 的情况下 show animated:YES 但 hide animated:NO 时会无法隐藏浮层的 bug。
  12. 保护 QMUIModalPresentationViewController 在快速 show/hide 时会错乱的问题。
  13. 修复 -[UIImage(QMUI) qmui_imageWithTintColor:] 在用半透明颜色处理一张不透明的图片时,最终输出的图片依然是不透明的,导致颜色处理错误的 bug。

4.1.1

4 years ago

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

  1. #939 调整配置表 NavBarShadowImageNavBarShadowImageColor 的作用,具体请查看 issue 内容。

如何适配新版

  1. 如果有使用配置表,请检查 App 运行后 NavBarShadowImageNavBarShadowImageColor 的表现是否正确。

Bugfix

  1. #937 修复使用了 QMUIAppearance 的 Class 如果被继承,则继承后的子类无法正常使用 appearance 的 bug。
  2. #938 修复 -[UIImage(QMUI) qmui_grayImage] 对 scale > 1 的图片处理后内容错误地以 scale = 1 的方式渲染的 bug。

4.1.0

4 years ago

新增功能

  1. 增加 QMUIAppearance 组件用于让非 UIViewNSObject 子类也可以使用 UIAppearance 能力,并将项目里相关组件都改为用 QMUIAppearanceImagePickerLibraryQMUIAlertControllerQMUIDialogViewControllerQMUIImagePreviewViewControllerQMUIModalPresentationViewControllerQMUIMoreOperationController
  2. 增加 NSObject (QMUIAppearnace),提供方法 -qmui_applyAppearance 用于将当前 Class 的 appearance 应用到当前实例上,该方法支持 UIView 和非 UIView 的任意对象。
  3. NSObject (QMUI) 增加 qmui_canGetValueForKey:qmui_canSetValueForKey: 用于判断某个给定的 key 是否可以用于当前对象的 KVC。
  4. #920 UINavigationController (QMU) 增加属性 qmui_interactivePopGestureRecognizerDelegate 用于获取系统原始的 interactivePopGestureRecognizer.delegate 的值。
  5. UIViewController (QMUI) 增加属性 qmui_prefersStatusBarHiddenBlockqmui_preferredStatusBarStyleBlockqmui_preferredStatusBarUpdateAnimationBlockqmui_prefersHomeIndicatorAutoHiddenBlock 便于在非继承的情况下依然能控制界面状态栏、Home Indicator。
  6. QMUIAlertController 增加属性 sheetButtonColumnCount 支持一行显示多个按钮。
  7. QMUIModalPresentationViewController 新增 willHideByDimmingViewTappedBlock 属性用于监听浮层即将被隐藏的时机。
  8. QMUIRuntime 增加 qmui_getProjectClassList() 函数用于获取业务项目的 Class 列表(不包含系统 Class 和引入的第三方 Framework)。
  9. QMUIOrderedDictionary 支持下标的语法操作。
  10. #691 QMUIPopupContainerView 增加 QMUIPopupContainerViewLayoutDirectionLeftQMUIPopupContainerViewLayoutDirectionRight 以支持水平方向的展示,QMUI Demo 也更新了展示示例。
  11. QMUIPopupContainerView 支持用 contentMode 切换内置图片、文本的布局方式。
  12. 配置表增加 TextFieldTextColor 用于全局设置 QMUITextFieldQMUITextViewtextColor,对 UITextFieldUITextView 不影响。

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

  1. 将 4.0.0-beta 就标记为已废弃的方法 shouldHoldBackButtonEventcanPopViewController 删除。

如何适配新版

  1. 全局 Matching Word 搜索“shouldHoldBackButtonEvent”、“canPopViewController”,将用到的地方改为新的方法“ shouldPopViewControllerByBackButtonOrPopGesture”。
  2. 如果有使用配置表,请将以下代码添加到配置表:
QMUICMI.textFieldTextColor = nil; // TextFieldTextColor : QMUITextField、QMUITextView 的 textColor,不影响 UIKit 的输入框
QMUICMI.shouldFixTabBarSafeAreaInsetsBugForNotchedScreen = NO; // ShouldFixTabBarSafeAreaInsetsBugForNotchedScreen : 是否要对 iOS 11 及以后的版本修复全面屏设备下 pop 界面时 UIScrollView 的 inset 会跳动导致滚动位置受影响的 bug(issue #934),默认为 NO

Bugfix

  1. #884 修复某些 UIModalPresentationStyle 情况下,present 起来的 viewController 无法响应 QMUITheme 切换的 bug。
  2. #900 修复 QMUIPieProgressView 在以动画的形式修改 progress 过程中 borderInset 失效的 bug。
  3. #906 修复 QMUICommonTableViewController 可能出现提前触发 loadView 的 bug。
  4. #914 优化配置表里对 StatusbarStyleLightInitially 的注释。
  5. #923 修复 QMUITheme 会强制用配置表的 KeyboardAppearance 值覆盖业务的值,导致某些界面如果想要与全局统一的键盘外观不一致,则无法实现的 bug。
  6. #930 修复与 DoraemonKit 冲突引发 dispatch_once 死锁的问题。
  7. #934 修复全面屏设备下,带 UITabBar 的界面在 push/pop 后,UIScrollView 的滚动位置可能发生变化的系统 bug,但默认代码是屏蔽的,需要手动将配置表里的 ShouldFixTabBarSafeAreaInsetsBugForNotchedScreen 置为 YES 才可以,具体请看如何适配新版
  8. 修复 QMUICollectionViewPagingLayout 在某些时候滑动时会滚动到错误 item 的 bug。
  9. 修复 QMUIImagePreviewView 在快速滚动时某些 index 的 imagePreviewView:willScrollHalfToIndex: 可能没有被触发的问题。
  10. 修复 QMUIFloatLayoutView.itemMargins.top 不生效的 bug。
  11. 修复 QMUIModalPresentationViewController 如果使用 contentViewController 的情况下无法重复 show 的问题。
  12. 修复 QMUIModalPresentationViewController 如果使用 contentViewController 的情况下,在调用 show 之前无法获取到 qmui_modalPresentationViewController 的问题。
  13. 修复 QMUIMultipleDelegates 无法使用 valueForKey:setValue:forKey: 的问题。
  14. 修复 iOS 13.4 下 UINavigationController 可能出现手势返回异常的情况。

4.0.4

4 years ago

新增功能

  1. UISwitch (QMUI) 增加 qmui_offTintColor 属性用于控制关闭时的背景色,对应地,配置表也增加了配置项 SwitchOffTintColor
  2. UILabel (QMUI) 增加 QMUILineHeightIdentity 用于重置 qmui_lineHeight 设置过的行高。
  3. #845 by @saucym NSArray (QMUI) 增加 qmui_mapWithBlock: 方法用于将数组的 item 转成别的类型。

如何适配新版

  1. 如果有使用配置表,请将以下代码添加到配置表:
    QMUICMI.switchOffTintColor = nil; // SwitchOffTintColor : UISwitch 关闭时的背景色(除了圆点外的其他颜色)
    

Bugfix

  1. #801 修复不同的 QMUIPopupContainerView 实例在同一个 UIBarButtonItem 上显示时,只有第一个浮层能正常显示的 bug。
  2. #802 修复 UIFont(QMUI) 在 iOS 13 下无法获取到正确的 Light 字体的 bug。
  3. #812 修复 QMUIMarqueeLabel 某些情况下无法看到文字的 bug。
  4. #813 修复 iOS13 以下应用内切换主题后 UITabBarItem 图片颜色不跟随主题变化的 bug。
  5. #814 修复 -[UINavigationController setViewControllers:]NeedsBackBarButtonItemTitle 不生效的 bug。
  6. #830 修复 iOS 13 UISearchBar.qmui_placeholderColor 在某些时机下设置时无效。
  7. #842 修复 QMUIFloatLayoutView.itemMargins 对处于外边缘(四条边上)的 item 会错误计算布局的 bug。