Releases: Tencent/QMUI_iOS
4.4.0
综述
4.4.0 版本主要内容是适配 iOS 15,同时废弃对 iOS 10 的支持。
iOS 15 对开发者而言最大的 UI 改动就是三种系统 bar(UINavigationBar、UITabBar、UIToolbar)默认样式都分为两个状态:滚动前、滚动后。只要你用 Xcode 13 打包,什么都不改的情况下就会出现这两种状态差异,而大部分 App 的预期应该是维持 iOS 14 相同的表现——因为 iOS 15 的这个特性只能在 iOS 15 上生效,系统无法向后兼容,这意味着如果你要保持系统这个特性,你就需要额外为自己的 App 在 iOS 15 上重新设计一套 bar 的外观。因此 QMUI 的兼容思路也是如此:在配置表提供若干开关,尽量减少业务项目达到“维持 App 外观不变”所需要付出的工作量。如果你的适配思路与此相悖,那么本次更新的内容可能对你作用不大,请降低预期。
另,如果你希望全 iOS 版本均能实现 iOS 15 这种滚动效果,建议使用 QMUINavigationBarScrollingAnimator
,它比系统功能更丰富,可以精准控制滚动过程中每一个时机的样式,可以联动除了 navigationBar、statusBar 之外的其他任何事情,而系统的仅仅只能定义起始和结束两个状态的 navigationBar 的属性,也无法监听当前的状态变化,局限性还是比较大的。以下是 QMUI Demo 中 QMUINavigationBarScrollingAnimator
功能的演示视频。
QMUINavigationBarScrollingAnimator.mov
新增功能
- 配置表增加开关
NavBarUsesStandardAppearanceOnly
,当业务项目打开的时候,会保持UINavigationBar.scrollEdgeAppearance
与UINavigationBar.standardAppearance
对齐,从而实现 iOS 15 上的导航栏在滚动前后样式一致。 - 配置表增加开关
NavBarRemoveBackgroundEffectAutomatically
,当业务项目打开的时候,会让UINavigationBar
在设置了backgroundImage
、barTintColor
时自动隐藏磨砂,在backgroundImage
、barTintColor
为nil
时自动显示磨砂(也即维持 iOS 14 的默认行为)。因为 iOS 15 及以后,backgroundEffect
可以和backgroundImage
、barTintColor
同时存在了,这与之前业务项目的代码逻辑的预期是不匹配的,要么你用这个开关来回到 iOS 14 的表现,要么你自己为 iOS 15 增加适配逻辑。 - 配置表增加开关
TabBarUsesStandardAppearanceOnly
、TabBarRemoveBackgroundEffectAutomatically
、ToolBarUsesStandardAppearanceOnly
、ToolBarRemoveBackgroundEffectAutomatically
,具体含义请参考上面的NavBar
,这里不再赘述。 - 配置表增加开关
TableViewSectionHeaderTopPadding
、TableViewGroupedSectionHeaderTopPadding
、TableViewInsetGroupedSectionHeaderTopPadding
,分别设置三种 style 的QMUITableView
在 iOS 15 上的sectionHeaderTopPadding
默认值,默认不修改的话,UITableViewStylePlain
会在每个 sectionHeader 之前多出来23pt的空白,另外两种 style 的列表与 iOS 14 一致。 QMUICommonDefines.h
增加宏IOS15_SDK_ALLOWED
用于区分当前是否是 Xcode 13 编译。QMUIAnimationHelper
增加接口bounceFromValue:toValue:time:coeff:
用于实现系统UIScrollView
拖到尽头那种阻尼感的体验。QMUILabel
增加属性truncatingTailView
用于在文字缩略时可以显示一个自定义的 View,具体可查看 QMUI Demo 的效果。
QMUIModalPresentationViewController
增加属性window
允许业务获取到 modal 内部正在使用的UIWindow
对象。QMUIModalPresentationViewController
增加属性shouldDimmedAppAutomatically
用于控制当前 modal 显示时是否需要把背后的 App 界面置灰(类似系统的UIAlertController
显示时的效果)。QMUIPopupContainerView
增加属性contentViewSizeThatFitsBlock
方便业务在外部控制 popup 内容的大小,而不一定非要继承一个子类。QMUIPopupContainerView
增加属性backgroundView
支持用一个自定义的 View(例如磨砂)作为 popup 的背景,当使用了这个属性后,arrowImage
只会作为遮罩来使用,不会显示arrowImage
图片内部的纹理(也即只用箭头的造型,不用它的内容)。
QMUIPopupContainerView
优化属性arrowImage
的实现,允许你将一张UIImageRenderingModeAlwaysTemplate
的图片作为箭头图片,当你这么做时,图片的颜色会自动跟随backgroundColor
走,从而避免以前设置了自定义箭头图片后再修改backgroundColor
,会看到箭头颜色与背景色不一致的问题。- #1295
QMUITextField
增加与QMUITextView
相同的canPerformPasteActionBlock
、pasteBlock
接口以支持控制粘贴事件(例如你可以在粘贴文本时把文本变成一张图放在输入框里)。 +[QMUIHelper deviceModel]
增加 iPhone 13、iPad 新设备的信息。- 增加协议
QMUIStringProtocol
,将原本NSString(QMUI)
支持的功能也迁移到NSAttributedString(QMUI)
内。 - 增加
UIBlurEffect(QMUI)
分类,提供qmui_effectWithBlurRadius:
支持指定明确的模糊半径,提供qmui_style
支持获取当前 blur 对象的 style 值。同时 QMUI Demo 内增加UIBlurEffect(QMUI)
的 Demo 展示。 UITableView(QMUI_InsetGrouped)
支持在 iOS 12 及以下的 Interface Builder 里设置 tableView 为InsetGrouped
。- #1290 @xixisplit
- [UIImage(QMUI) qmui_imageWithGradientColors:]
增加QMUIImageGradientTypeTopLeftToBottomRight
、QMUIImageGradientTypeTopRightToBottomLeft
类型。
会带来 QMUI 新旧版本兼容问题的更新
- 为了适配 iOS 15,
UINavigationBar
、UIToolbar
从这个版本开始,改为用 iOS 13 就提供的新系统接口UINavigationBarAppearance
、UIToolbarAppearance
来设置样式(UITabBar
的在 QMUI 4.0.0 适配 iOS 13 时就已经换成新接口了),新旧接口是互斥的,一旦项目里某个地方用了新接口,整个项目的旧接口都会失效。但为了尽量减少业务项目更新 QMUI 版本的工作量,我们在UINavigationBar(QMUI)
、UIToolbar(QMUI)
内对旧接口做了映射,统一转换为新接口,因此预期业务项目更新版本后应该不会出现UINavigationBar
、UIToolbar
的样式差异问题。 - 由于最低版本从 iOS 10 升级到 iOS 11,因此去掉了 QMUI 内所有为 iOS 10 写的代码,并且以前为了兼容 iOS 11 才有的 API 而加的接口(例如
qmui_safeAreaInsets
)也没必要了。 - 由于 #1325 的问题,再考虑到该功能原本的实现代码有些混乱,因此这个版本重构了
AutomaticCustomNavigationBarTransitionStyle
的实现,减少了对QMUINavigationControllerAppearanceDelegate
系列接口多次不必要的调用,并且更稳定。 - 由于现如今
QMUIButton
的功能已足够灵活,相比之下基于它衍生的QMUIFillButton
、QMUIGhostButton
显得有点鸡肋,且预设的 enum 难以准确满足业务项目的配色需求,因此这个版本我们将QMUIFillButton
、QMUIGhostButton
删除,建议原本在用的项目将其改为QMUIButton
,或者你也可以复制这两个类的文件放在业务项目里继续使用。 - 4.3.0 里标记为废弃的
QMUILinkButton
在 4.4.0 里正式删除。 - 更换
QMUITheme
在 iOS 13 及以后的系统里监听系统userInterfaceStyle
变化的方式,从而达到:- 避免之前监听
-[UIWindow traitCollection]
会导致每次有任何界面操作(触摸、按下键盘快捷键、Dark Mode 切换)时都会触发这段逻辑,而我们仅仅只希望利用它来监听 Dark Mode 切换而已。 - #1087 #1318 避免之前 hook
-[UIWindow traitCollection]
导致在 Xcode 唤醒的场景里 App 第一次升起键盘会触发 Main Thread Checker 的问题。 - 旧的实现方案在系统
userInterfaceStyle
发生变化,到 QMUITheme 成功切换之间的耗时较长,在此期间访问QMUIThemeManager.currentTheme
得到的值必定都是错误的(例如这过程中就会触发 UIViewController preferredStatusBarStyle,而业务项目在该方法里获取当前 QMUIThemeManager.currentTheme 的操作还是比较常见的)问题。
- 避免之前监听
- 去掉
QMUIThemePrivate
里重写-[UIView setBackgroundColor:]
、-[UITableViewCell setBackgroundColor:]
的代码,实测 iOS 11-15 均不需要这种处理了,而这段代码会导致QMUIThemeColor
无法搭配UIViewPropertyAnimator
使用。 - 去掉
QMUIThemePrivate
里重写-[UITextField setNeedsDisplay]
的代码,实测不需要。 QMUIHelper
重命名is61InchScreenAndiPhone12
为is61InchScreenAndiPhone12Later
,重命名screenSizeFor61InchAndiPhone12
为screenSizeFor61InchAndiPhone12Later
。QMUIHelper.safeAreaInsetsForDeviceWithNotch
对全面屏 iPad 返回的 top 值从 0 改为 24。QMUIHelper.resetDimmedApplicationWindow
的实现里,把 Normal 改为系统默认的 Automatic(免测)。- 配置表开关
NavBarButtonFontBold
在 iOS 15 里对系统的 Done 类型的UIBarButtonItem
也能生效,iOS 14 及以前只能对QMUINavigationButtonTypeBold
才生效。 - 删除配置表开关
StatusbarStyleLightInitially
,新增配置表开关DefaultStatusBarStyle
,新开关的类型为UIStatusBarStyle
,可以支持精准的状态栏样式控制,从而避免类似 #1311 的问题。
如何适配新版
- 全局搜索“QMUIFillButton”、“QMUIGhostButton”,将用到的地方换成
QMUIButton
,如果较多,建议在项目里创建工具方法(可以参考 QMUI Demo 里的+[QDUIHelper generateGhostButtonWithColor:]
。或者也可以将这两个被删除的文件移到业务项目中继续使用。 - 全局搜索“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
- 全局搜索”qmui_safeAreaInsets“,将其替换为系统的
safeAreaInsets
,前者依然能用但已被标记为废弃,下个版本会删除。 - 全局搜索”qmui_contentInset“,将其替换为系统的
adjustedContentInset
,前者依然能用但已被标记为废弃,下个版本会删除。 - 全局搜索”qmui_maskedCorners“,将其替换为系统的
maskedCorners
,前者依然能用但已被标记为废弃,下个版本会删除。 - 全局搜索”qmui_performBatchUpdates“,将其替换为系统的
performBatchUpdates
。 - 全局搜索 “is61InchScreenAndiPhone12”,将其重命名为 “is61InchScreenAndiPhone12Later”。
- 全局搜索 “screenSizeFor61InchAndiPhone12”,将其重命名为“screenSizeFor61InchAndiPhone12Later”。
- 检查用到
QMUIHelper.safeAreaInsetsForDeviceWithNotch
的地方在 iPad 上是否正常。 - 检查用到
AutomaticCustomNavigationBarTransitionStyle
效果的地方是否正常。 - 检查将
QMUIThemeColor
作为UIView.backgroundColor
、UITableViewCell.backgroundColor
的地方,theme 切换时是否正常。 - 检查 theme 切换时
UITextField
的文字颜色是否正常。 - 如果项目有使用 QMUITheme,请检查 App 的 Dark Mode 功能是否正常,特别留意 App 在后台、有键盘升起的时候。另外请检查项目里是否有使用
UITraitCollection.currentTraitCollection.userInterfaceStyle
来判断当前 App 样式的写法,有的话,请去掉并改为用QMUIThemeManagerCenter.defaultThemeManager.currentThemeIdentifier
,因为前者这个系统的方法在 Dark Mode 切换过程中可能会得到错误的值。
如果有使用配置表
- 请删除包含”fillButton“、”ghostButton“字样的10个开关。
- 在
#pragma mark - NavigationBar
分段里添加以下开关,并将其设置为项目所需的值。请保证语句的顺序在其他 navBar 开关之前。if (@available(iOS 15.0, *)) { QMUICMI.navBarUsesStandardAppearanceOnly = NO; QMUICMI.navBarRemoveBackgroundEffectAutomatically = NO; }
- 在
#pragma mark - TabBar
分段里添加以下开关,并将其设置为项目所需的值。请保证语句的顺序在其他 tabBar 开关之前。if (@available(iOS 15.0, *)) { QMUICMI.tabBarUsesStandardAppearanceOnly = NO; QMUICMI.tabBarRemoveBackgroundEffectAutomatically = NO; }
- 在
#pragma mark - Toolbar
分段里添加以下开关,并将其设置为项目所需的值。请保证语句的顺序在其他 toolBar 开关之前。if (@available(iOS 15.0, *)) { QMUICMI.toolBarUsesStandardAppearanceOnly = NO; QMUICMI.toolBarRemoveBackgroundEffectAutomatically = NO; }
- 将下方代码添加到配置表里的适当位置,并将其设置为项目所需的值。
if (@available(iOS 15, *)) { QMUICMI.tableViewSectionHeaderTopPadding = UITableViewAutomaticDimension; QMUICMI.tableViewGroupedSectionHeaderTopPadding = UITableViewAutomaticDimension; QMUICMI.tableViewInsetGroupedSectionHeaderTopPadding = UITableViewAutomaticDimension; }
- 请检查项目里用到的 Done 类型的
UIBarButtonItem
,字体样式是否符合预期。 - 将下方代码添加到配置表里,并将其设置为项目所需的值。同时全局搜索”StatusbarStyleLightInitially“字样,将用到的地方换成新的”DefaultStatusBarStyle“。
QMUICMI.defaultStatusBarStyle = UIStatusBarStyleDefault; // DefaultStatusBarStyle : 默认的状态栏样式,默认值为 UIStatusBarStyleDefault,也即在 iOS 12 及以前是黑色文字,iOS 13 及以后会自动根据当前 App 是否处于 Dark Mode 切换颜色。如果你希望固定为白色,请设置为 UIStatusBarStyleLightContent,固定黑色则设置为 QMUIStatusBarStyleDarkContent。
Bugfix
- #1276 修复 QMUITextView 重写错 init 方法,导致 initWithFrame:textContainer: 无法应用初始值的 bug。
- #1308 #1316 修复在输入框内长按移动光标时会错误触发
UIGestureRecognizer(QMUI)
assert 的问题。 - #1312 修复启动时试图通过
qmui_getProjectClassList
获取项目里所有业务 Class 失败的 bug。 - #1320 修复
- [QMUITableViewCell initForTableView:xxx]
方法的实现不恰当,可能引起 Swift 内重复调用 init 的问题。 - #1322 @ACFancy 修复
QMUITextField
、QMUITextView
在进行”重做“操作时依然可能引发 #1168 里描述的问题的 bug。 - 修复
QMUIPopupMenuView
在itemTitleFont
、itemTitleColor
、padding
的值发生变化时没有刷新 item 样式的 bug。 - 修复 `U...
4.3.0
新增功能
QMUICommonDefines.h
增加宏QMUIAssert
用于代替NSAssert
,作用是当业务使用QMUIConsole
且打开了配置表ShouldPrintQMUIWarnLogToConsole
时,该 assert 会把信息显示到QMUIConsole
面板里,而不会触发NSAssert
,从而避免中断程序的运行。但如果业务项目没打开ShouldPrintQMUIWarnLogToConsole
,则该宏等价于NSAssert
。UIViewController(QMUI)
增加qmui_isSystemContainerViewController
方法(共两个,一个是类方法,一个是实例方法)用于判断当前的 viewController 是否为系统自带的 Container View Controller(例如UINavigationController
、UITabBarController
)。QMUIGridView
增加padding
属性用于设置内部的间距。QMUIKeyboardManager
增加isFloatingKeyboard
属性用于判断当前是否为 iPad 上的浮动键盘。QMUIPopupMenuBaseItem
、QMUIPopupMenuButtonItem
的height
属性支持赋值为QMUIViewSelfSizingHeight
,以使每一行的高度自动根据当前行的内容来计算。在此之前该高度仅支持写死的固定值。QMUISearchController
增加initWithContentsViewController:resultsTableViewStyle:
方法用于指定搜索结果列表的 style。QMUISearchController
增加dimmingColor
用于设置搜索框聚焦键盘升起时的遮罩颜色。QMUIWeakObjectContainer
增加isQMUIWeakObjectContainer
用于判断当前对象是否为QMUIWeakObjectContainer
,同时修复 QMUI 里若干用到这个类的地方判断写法不正确的问题(虽然写法不正确,但由于内部会做消息转发,所以不会引起实质性问题)。QMUIHelper
增加canUpdateAppearance
属性用于判断当前是否可以设置UIAppearance
,该方法主要用于解决 #1281,具体请查看下方专项说明。QMUIHelper
增加topMarginForAttributedImage:attributes:
可以根据图片大小、图片所在的富文本样式,计算得出一个能让图片在当前富文本里垂直居中的顶部偏移值。- 新增
UIApplication(QMUI)
分类,提供qmui_didFinishLaunching
属性用于判断当前 App 是否已完全启动。 NSAttributedString(QMUI)
增加qmui_attributedStringWithImage:alignByAttributes:
方法用于把UIImage
转为NSAttributedString
并利用参数的属性来自动调整 image 的垂直位置。NSAttributedString(QMUI)
增加qmui_attributedStringWithImage:margins:
用于把UIImage
转为NSAttributedString
并利用参数调整 image 的上下左右布局偏移。NSString(QMUI)
增加qmui_stringMatchedByPattern:groupIndex:
、qmui_stringMatchedByPattern:groupName:
方法支持使用正则表达式匹配字符串后返回指定分组的结果。UIButton(QMUI)
增加qmui_setImageTintColor:forState:
方法用于便捷地给不同状态的 image 设置不同颜色。UIControl(QMUI)
增加qmui_setSelectedBlock:
、qmui_setEnabledBlock:
便于在 selected、enabled 发生变化时做一些事情。- 增加
UIFontMediumMake
、UIFontMediumWithFont
、UIDynamicFontMediumMake
、UIDynamicFontMediumMakeWithLimit
宏,以及-[UIFont(QMUI) qmui_mediumSystemFontOfSize:]
方法用于生成 Medium 字重的字体。 UIImage(QMUI)
增加qmui_imageWithGradientColors:type:locations:size:cornerRadiusArray:
方法用于生成一张渐变图片。UILabel(QMUI)
增加属性qmui_showPrincipalLines
可以显示当前文字的 descender、xHeight、capHeight、lineHeight,便于调试。UITextField(QMUI).qmui_selectedRange
属性从readonly
改为readwrite
,方便业务通过NSRange
形式去修改选中的区域,不用人工做一次类型转换。UITextView(QMUI)
增加qmui_selectedRange
便于获取NSRange
类型的选中区域。UIView(QMUI)
增加qmui_fixedSize
属性用于简单地把某个 view 设置为固定大小,通常使用的场景是某个网络上加载下来的图片(大小不确定)要放在某个 UIButton 上,并且希望不管什么图都固定显示为某个 size,以前通常只有两种方式来实现:一是将图片裁剪为指定大小,二是重写一个自定义的 UIButton,现在可以简单地设置 UIButton.imageView.qmui_fixedSize 即可。UIView(QMUIBorder)
增加qmui_borderInsets
用于调整边框的偏移值,具体效果可查看 QMUI Demo 里的 UIView+QMUI 示例。
会带来 QMUI 新旧版本兼容问题的更新
- #1231 #1284 近期若干个 App 提交 App Store 时会被拒绝,提示“The app references non-public selectors in Frameworks/QMUIKit.framework/QMUIKit: navigationBarBackgroundImage, navigationBarStyle, navigationBarTintColor”,但大部分 App 没收到这个提醒。其中提到的几个方法均为 QMUI 开天辟地时就存在的方法命名,之前一直没问题,暂不清楚原因。目前只能将其重命名,增加
qmui_
前缀以避免审查。 - 废弃
QMUILinkButton
,该组件的能力完全可以用新版的UIView(QMUIBorder)
代替。 - 废弃
QMUIVisualEffectView
,该组件的能力完全可以用UIVisualEffectView(QMUI)
代替。但须注意这两者有细微的色差——系统的UIVisualEffectView
内部由“磨砂+半透明前景色”组成,而QMUIVisualEffectView
的实现方式是在系统基础上再叠加一个前景色,也即“磨砂+系统前景色+QMUI 前景色”,但UIVisualEffectView.qmui_foregroundColor
是把系统自带前景色去掉后再叠加一层前景色,也即“磨砂+QMUI 前景色”,从而能更精准控制磨砂的样式。但更换为新版后,业务的磨砂效果应该会变得更明显,需要业务自行检查是否要重新调整foregroundColor
。 - 删除配置表
SwitchTintColor
开关,这个开关仅在 iOS 12 及以前才有效,作用是在UISwitch
关闭时显示外圈的颜色,一般没什么用,就不再提供了。 - 将
-[NSAttributedString(QMUI) qmui_attributedStringWithImage:baselineOffset:leftMargin:rightMargin:]
标记为已废弃,且很快会在后续版本删除,请尽快使用新增的qmui_attributedStringWithImage:margins:
代替。 - 删除
QMUICustomizeButtonPropType
及关联的qmui_hasCustomizedButtonPropForState:
、qmui_hasCustomizedButtonPropWithType:forState:
方法,忘了当初为什么加这些东西了。 UILabel(QMUI).qmui_lineHeight
属性原本只是简单地设置文字的 lineHeight,但由于 iOS 的特性,不管 lineHeight 设置为多少,文字都是居底部对齐,但市面上基本所有的设计软件(如 figma、sketch),以及其他平台的布局代码,默认都是文字在行高内垂直居中,这容易导致布局还原效果差,需要反复调整,因此这版本里qmui_lineHeight
默认会使文字垂直居中,项目里原本使用该属性的地方,更新版本后间距可能会变化,需要业务项目检查。经过衡量,我们认为长远来看该更新成本是值得的。
如何适配新版
- 以 Matching Word 形式全局 Replace
QMUINavigationControllerAppearanceDelegate
里的7个方法,加上“qmui_”前缀。 - 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
- Matching Word 形式全局搜索“QMUIVisualEffectView”,将用到的地方改为
UIVisualEffect.qmui_foregroundColor
,并检查其效果是否符合业务的需求。 - 全局搜索用到
-[NSAttributedString(QMUI) qmui_attributedStringWithImage:baselineOffset:leftMargin:rightMargin:]
的地方,将其改为新方法-[NSAttributedString(QMUI) qmui_attributedStringWithImage:margins:]
。 - 全局搜索 “QMUICustomizeButtonPropType”、
qmui_hasCustomizedButtonPropForState:
、qmui_hasCustomizedButtonPropWithType:forState:
,如果有用到,请将相关的 QMUI 旧代码复制为业务代码使用。 - 全局搜索用到“qmui_lineHeight”的地方,查看该地方的布局是否有问题(更新 QMUI 后布局应该会比之前偏上)。
- 如果有使用配置表,请删除其中的“SwitchTintColor”相关代码。
Bugfix
- #1152 #1159 #1227 #1278 重新优化“Main Thread Checker: UI API called on a background thread: -[UIWindow traitCollection]”的问题。
- #1180 修复没有使用
QMUINavigationController
的情况下,执行 pop 操作时可能依然还在上一次转场动画过程中,此次的 pop 会被系统忽略,导致命中UINavigationController (QMUI)
里的 NSAssert 的问题。 - #1232 修复
UISearchBar(QMUI).qmui_alwaysEnableCancelButton
可能出现 crash 的 bug。 - 修复
UISearchBar(QMUI)
在没有设置qmui_cancelButtonMarginsBlock
的情况下 qmuisb_shouldFixLayoutWhenUsedAsTableHeaderView 无效的 bug。 - #1243 [UIKit Bug] 修复 iOS 11 及以上,关闭 estimated height 的 tableView 可能出现数据错乱引发 crash 的 bug。
- #1246 修复
QMUIButton.highlightedBackgroundColor
没有兼容qmui_maskedCorners
的 bug。 - #1253 修复配置表
AutomaticCustomNavigationBarTransitionStyle
为YES
的效果在 pop 时可能出错的 bug。 - #1257 #1263 修复在非全面屏的 Regular 设备里,仅支持竖屏的 App 在横屏启动时界面错乱的 bug。
- #1258 修复
QMUITextView
在使用placeholder
的情况下调用sizeToFit
会出现NaN
的 bug。 - #1281 [UIKit Bug] 修复 App 处于后台时修改 UIAppearance 里 UIImage 类型的属性很大几率导致第三方键盘 crash 的 bug。——该 bug 很重要,在下文专项说明
- #1282 修复
QMUITextField
通过代码setText:
修改文字后,光标无法正确置于文字末尾的 bug。 - #1283 修复
-[UIButton(QMUI) qmui_setTitleAttributes:forState:]
在 iOS 12 及以下系统无效的 bug。 - #1286 [UIKit Bug] 修复使用
UITabBarAppearance
将UITabBarItem
选中时的字体设置为 bold 则无法完整显示 title 的 bug。 - 重构
-[UIButton(QMUI) qmui_setTitleAttributes:forState:]
方法,修复其他 state 下无法设置 title 的 bug。 - 修复
-[QMUIButton sizeThatFits]
在参数为CGSizeZero
时错误返回了高度为 0 的大小(系统UIButton
在这种情况下会返回真实内容大小)。 - 修复
QMUIMultipleDelegates
与RAC
冲突导致死循环的 bug。 - 修复
QMUISearchController
在 iPad 分屏时用QMUIEmptyView
显示空结果的情况下,改变分屏的比例,QMUIEmptyView
的宽度没有刷新的 bug。 - 修复
QMUITextView
设置了textAlignment
为Right
后placeholder
样式没同步的 bug。 - 修复
QMUIThemeImage
在使用resizableImageWithCapInsets:
、resizableImageWithCapInsets:resizingMode:
后无法保持其动态特性的 bug。 - 修复 iOS 10-11,
QMUITheme
动态颜色在UILabel.textColor
上无法及时刷新的 bug。 - 修复
QMUITheme
里处理keyboardAppearance
的逻辑会对UITextField
内部的UIFieldEditor
也生效的 bug。 - 修复关闭 theme 主题跟随系统的开关后,切换 App 里的 Light/Dark theme,
UITabBar
的backgroundEffect
值刷新但样式没刷新的 bug。 - 修复
UITraitCollection(QMUI)
里没有对 window 过滤 nil 导致 App 从桌面唤醒时可能无法立即显示正确的 style 的 bug。 - 修复
UIView(QMUIBorder)
在不显示 border 时依然会触发多次不必要的 setNeedsLayout 的 bug。 - 修复
QMUIKeyboardManager
在某些情况下键盘 hide 过程中还会触发 show 的 bug。
其他
QMUIAlertController
内部的titleLabel
、messageLabel
类型从UILabel
改为QMUILabel
以支持长按复制。- 将分类
NSMutableParagraphStyle(QMUI)
改为NSParagraphStyle(QMUI)
以支持更多类型。 - 监听
UIGestureRecognizer
执行过程中是否被禁用(典型案例是试图在viewWillAppear:
里禁用当前界面的手势返回,这样会导致从当前界面的下一个界面手势返回时界面卡死)。 UINavigationController(QMUI)
增加对pushViewController:
、setViewControllers:
的保护,避免重复 push 触发系统的 crash。- 优化
UIVisualEffectView(QMUI).qmui_foregroundColor
,当开启系统的“降低透明度”辅助功能开关后, 屏蔽它的半透明效果,避免出现怪异表现。
关于 #1281 的特别说明
近期我们意识到在使用 QMUI 的 App 里,第三方键盘很容易被系统杀掉重启,经过一番测试,证实确实与 QMUI 有关,但问题的根源在于系统的 UIAppearance 协议在某些场景下的使用会导致内存暴涨,而 QMUI 刚好命中了这些场景。具体的分析解释请查看 #1281 (comment) ,建议必读。
总结来说,使用 QMUI 的项目要规避这个问题,不能仅依靠 QMUI 自己的更新,业务项目也需要同步配合进行以下几个措施:
- 更新最新版的 QMUI(4.3.0 及后续版本)。
- 配置表里
UIImage
、UIColor
的属性,都用一个全局变量存起来,目的是为了保证切换 theme 时不会重新赋值(指针相同就不会执行 setter)。 - 搜索项目业务代码,确保在 theme 变化时会设置的 UIAppearance 逻辑,用
if (QMUIHelper.canUpdateAppearance)
的判断包起来。
做完以上举措后,可以用最新版 QMUI Demo 验证效果(内置 Keyboard Extension)。
- 在你的模拟器/真机上运行 QMUI Demo,此时设置里会出现新键盘“QMUIKeyboard-QMUI(Debug)”,将其添加为唯一的输入法。
- 打开你的 App,点击某个输入框以升起 QMUI 键盘,可看到键盘上显示了一个数字。
- 保持键盘显示的状态,不断重复“回到桌面-打开App-回到桌面”,观察键盘上的数字是否稳定“每次增加固定值”,例如以 QMUI Demo 为例,每次都会增加5。
如果测试结果符合第3点,该数字没有指数型上升,就意味着你的业务项目是正常的,可以放心使用。
4.2.3
新增功能
- 增加
UICollectionView(QMUI)
提供qmui_selectedBackgroundColor
属性便于设置点击时的背景色,同时也更便于兼容QMUITheme
。 QMUIEmotionView
增加verticalAlignment
等若干属性以支持类似微信的竖向滚动交互。QMUIButton
增加属性cornerRadius
用于更方便地设置按钮圆角,同时提供常量QMUIButtonCornerRadiusAdjustsBounds
使其可以维持圆角为按钮高度的一半,不用业务自己在按钮大小发生变化时更新圆角值。UIColor(QMUI)
增加方法qmui_distanceBetweenColor:
用于计算两个颜色之间的相近程度,原理是将两个颜色转换为 HSB 模型后取两点之间的距离,注意该方法会忽略 alpha 通道。UISearchBar(QMUI)
增加属性qmui_searchController
用于获取与当前 searchBar 绑定的UISearchController
对象。UISearchBar(QMUI)
增加属性qmui_alwaysEnableCancelButton
支持当某个 searchBar 脱离UISearchController
存在时,强制使其cancelButton
一直处于enabled
状态(系统默认在输入框聚焦时 enabled,失焦时 disabled,这通常不是我们想要的)。UITabBar(QMUI)
增加属性qmui_effectView
用于获取内部的磨砂 view。UITabBar(QMUI)
增加属性qmui_effect
支持直接修改 tabBar 的磨砂类型(系统仅在 iOS 13 及以后才支持)。UITabBar(QMUI)
增加属性qmui_effectForegroundColor
支持精准指定 tabBar 磨砂的前景色,系统默认是无法做到这一点的,因为UIVisualEffectView
在某些 blur style 下会有自带的一层前景色,且无法修改,你设置的前景色最终会和系统的前景色叠加,导致总是无法精准实现业务所需效果。UITableView(QMUI)
增加属性qmui_indexFrame
用于获取 tableView 右边那条sectionIndex
索引条的frame
。UITableViewCell(QMUI)
增加属性qmui_didAddToTableViewBlock
便于在 cell 能拿到 tableView 引用的第一时间做一些事情,例如根据不同 style 的 tableView 作不一样的样式区分。UITableViewCell(QMUI)
增加属性qmui_configureStyleBlock
让 cell 层面也能得到willDisplayCell
的渲染时机,在这个 block 里你可以拿到 tableView 的引用,也可以知道当前 cell 的indexPath
、qmui_cellPosition
等信息,便于你做一些全局样式的管理。-[UIImage imageWithTintColor:]
、-[UIImage qmui_imageWithTintColor:]
支持将静态 image 和动态 color 组合为动态 image,在此之前你需要手动创建一个动态 image,在 provider block 里根据动态 color 的不同值生成不同的 image。
会带来 QMUI 新旧版本兼容问题的更新
- 由于
QMUIButton
增加的cornerRadius
圆角接口,原本在子类QMUIFillButton
、QMUIGhostButton
里自行实现的cornerRadius
均被去除,对应的常量QMUIFillButtonCornerRadiusAdjustsBounds
、QMUIGhostButtonCornerRadiusAdjustsBounds
也一并删除。 - 将上个版本被标记为已废弃的
+[QMUIThemeManager sharedInstance]
方法彻底删除。 - #1193 由于修复
UIViewController.qmui_tabBarSpacingInViewCoordinator
未考虑hidesBottomBarWhenPushed = YES
的情况的 bug,所以以前某个 vc 如果hidesBottomBarWhenPushed = YES
,但却利用qmui_tabBarSpacingInViewCoordinator
去获取布局信息,那么在新版本更新后,这个 vc 里拿到的值将为 0。0 是正确的,因为此时 tabBar 不可见,但却可能导致业务界面产生与 QMUI 4.2.2 不同的表现。 - #1219
QMUINavigationControllerTransitionDelegate
里提供的接口navigationController:poppingByInteractiveGestureRecognizer:viewControllerWillDisappear:viewControllerWillAppear:
无法直观判断手势返回最终是成功了还是取消了,因此新版本为其增加了新参数isCancelled
,同时将旧方法标记为废弃,建议尽快替换为新方法。 - 由于设计师的回归,这个版本 QMUI Demo 调整了默认的 logo、配色,理论上不应该对业务项目产生任何影响(因为 QMUI Demo 是一个独立的示例项目),但保险起见,在 Release Note 里明确写出。
如何适配新版
- 全局搜索“QMUIFillButtonCornerRadiusAdjustsBounds”、“QMUIGhostButtonCornerRadiusAdjustsBounds”,将其换成新的
QMUIButtonCornerRadiusAdjustsBounds
。 - 全局搜索使用
+[QMUIThemeManager sharedInstance]
的地方,将其删除,并考虑用QMUIThemeManagerCenter.defaultThemeManager
代替。 - 全局搜索用到
qmui_tabBarSpacingInViewCoordinator
的地方,检查该界面是否hidesBottomBarWhenPushed = YES
且非UINavigationController
的rootViewController
,如果存在该情况,请注意它的布局是否正常。 - 全局搜索用到
navigationController:poppingByInteractiveGestureRecognizer:viewControllerWillDisappear:viewControllerWillAppear:
的地方,为其增加参数isCancelled
,具体参数的位置请查看 QMUI 源码。
Bugfix
- #999 修复
QMUITextView
在输入过程中从一行换到两行时会产生的跳动问题,同时修复QMUITextView
初始化后通过代码设置 text,后续手动聚焦输入文字瞬间会跳动的 bug。 - #1161 [UIKit Bug] 修复将
UISearchBar
作为tableHeaderView
使用的UITableView
,如果同时设置了estimatedRowHeight
,则contentSize
会错乱,导致滚动异常的系统 bug。 - #1176 修复在 MainThreadChecker 开启的状态下使用了
QMUITheme
后可能导致“directTraitCollectionIMP EXC_BAD_ACCESS”的 bug。 - #1177 修复 iOS 14.0-14.2,
setViewControllers:
去到一个hidesBottomBarWhenPushed = NO
的界面会 crash 的 bug。 - #1180 修复
UINavigationController
不可见的情况下进行 pop 操作会命中 UINavigationController+QMUI.m 内的 NSAssert 的问题,同时借机优化 #261 里-[UINavigationController pushViewController:animated:]
对isViewControllerTransiting
的使用逻辑。 - #1181 修复
QMUITextView
在显示placeholder
时sizeThatFits:
返回的结果没有包含placeholder
占位大小的 bug。 - #1187 修复
-[UITabBarItem(QMUI) qmui_imageViewInTabBarButton:]
方法在打开了系统的“辅助功能-显示与文字大小-按钮形状”后无法获取到正确 imageView 的 bug。 - #1190 修复 iOS 12 及以下,在
rootViewController
、以animated:NO
进行的 push/pop 界面,- [QMUINavigationControllerDelegate titleViewTintColor]
无效的 bug。 - #1192 修复
- [QMUIMultipleDelegates respondsToSelector:]
不支持NSProxy
类型的 delegate 成员的 bug。 - #1198 修复
+[QMUIHelper isRegularScreen]
对 iPhone 12/12 Pro 判断错误,导致横屏时获取导航栏高度错误的 bug。 - #1200 修复
QMUIConsole
在子线程里输出 log 会 crash 的 bug。 - #1207 [UIKit Bug] 修复将
UISearchBar
作为UITableView.tableHeaderView
使用时,如果列表内容不满一屏,可能出现搜索框不可视的系统 bug。 - #1210 修复
- [QMUINavigationControllerDelegate titleViewTintColor]
在 iOS 12 下手势返回又取消后可能出错的 bug。 - #1213 [UIKit Bug] 修复
UISearchBar
作为tableHeaderView
使用时,切换 tableView 的sectionIndex
的显隐,searchBar 的布局可能无法刷新的系统 bug。 - #1215 [UIKit Bug] 修复将
UISearchBar
作为tableHeaderView
使用的UITableView
,在 tableView 尚未添加到 window 上就同时进行了setTableHeaderView:
、reloadData
的操作,会导致滚动异常的系统 bug。 - #1216 修复 iOS 12 及以下,
QMUITableViewStyleInsetGrouped
在编辑、排序状态下布局错误的 bug。 - #1217 [UIKit Bug] 修复 iOS 12 及以上的系统,如果设置了自己的
leftBarButtonItem
,且 title 很长时,则当 pop 的时候,title 会瞬间跳到左边,与leftBarButtonItem
重叠的系统 bug。 - #1218 修复
UITabBarItem.selectedImage
无法二次更新的 bug。 - 修复高帧率设备下
QMUIDisplayLinkAnimation
动画时长减半的 bug。 - 修复
QMUINavigationBarScrollingAnimator
的barTintColorBlock
属性无效的 bug。 - 修复
NSString(QMUI)
提供的qmui_substringAvoidBreakingUpCharacterSequencesFromIndex:lessValue:countingNonASCIICharacterAsTwo:
、qmui_substringAvoidBreakingUpCharacterSequencesToIndex:lessValue:countingNonASCIICharacterAsTwo:
这两个方法里当参数countingNonASCIICharacterAsTwo
为YES
时,没有将参数index
按照countingNonASCIICharacterAsTwo
的规则来计算的 bug。 - 修复
UITableView(QMUI).qmui_validContentWidth
属性在列表出现右边的 sectionIndex 索引条时返回的宽度错误的 bug。
其他
- #1166
QMUIConsole
的实现从 textView 改为 tableView,以优化在展示大量 log 时的性能,同时也优化了搜索的关键词高亮体验。 - #1220 优化 QMUI 内的
valueForKey:
用法可能存在一些风险。 - #1214 @0x1306a94 兼容未启用
CLANG_ENABLE_MODULES
时通过 CocoaPods 集成会产生的编译错误。 - 配置表
NavBar
系列属性发生变化时会去刷新当前界面的 navigationBar,如果该界面有通过QMUINavigationControllerDelegate
提供的统一接口去自定义业务界面自己的样式,则配置表不需要强制帮它刷新。
4.2.2
新增功能
UINavigationController (QMUI)
增加方法qmui_didInitialize
方便子类重写 init 时的逻辑,因为系统的UINavigationController
总共有4个NS_DESIGNATED_INITIALIZER
,子类每次都重写这4个方法成本过高也容易遗漏。UINavigationController (QMUI)
增加QMUINavigationAction
枚举用于标志当前 navigationController 的导航动作状态,并提供对应的qmui_navigationAction
qmui_addNavigationActionDidChangeBlock:
方法便于在某些导航动作产生时做一些事情,免去每个地方自己 hook/override 一遍 setViewControllers、pushViewController、popViewController、popToViewController、... 的麻烦(且 pop 操作有多种,容易遗漏)。- [QMUINavigationControllerAppearanceDelegate titleViewTintColor]
接口现在对系统的 title 也可以生效(以前仅对QMUINavigationTitleView
才生效)。- 增加
UINavigationItem (QMUI)
,提供多个接口方便访问关联的 navigationBar、navigationController 等信息。 UIViewController (QMUI)
增加qmui_isDescendantOfViewController:
用于判断当前 vc 是否为指定 vc 本身,或者是其 childViewController、childViewController 的 childViewController、...。- QMUIHelper 增加系列接口对应新发布的 iPhone 设备:
is67InchScreen
is61InchScreenAndiPhone12
is54InchScreen
screenSizeFor67Inch
screenSizeFor61InchAndiPhone12
screenSizeFor54Inch
- #1146 @ZenonHuang QMUIHelper 更新
deviceName
以兼容新发布的设备。 QMUIHelper
增加方法isMac
、QMUICommonDefines.h 增加宏IS_MAC
用于区分是否 Mac Catalyst App 或 iOS 项目直接在 M1 设备上运行的情况。- QMUICommonDefines.h 增加宏
PreferredValueForInterfaceIdiom(_phone, _pad)
用于区分 phone、pad 两种情况,注意当 iPad 分屏时,如果 App 窗体宽度较窄,也会被视为 phone。 - QMUIRuntime.h 增加
qmui_exists_dyld_image
函数用于检测是否存在某个 dyld image。 UITextField (QMUI)
增加方法qmui_convertNSRangeFromUITextRange:
、qmui_convertUITextRangeFromNSRange:
便于类型转换。- [QMUIModalPresentationViewControllerDelegate shouldHideModalPresentationViewController:]
现在支持所有显示类型了,之前仅对 window 方式有效。- #1142
QMUIOrderedDictionary
增加allValues
属性。 - #1108 #1113 配置表增加
NavBarContainerClasses
用于限定 NavigationBar 系列开关的生效范围,增加TabBarContainerClasses
用于限定 TabBar 系列开关的生效范围,增加ToolBarContainerClasses
用于限定 Toolbar 系列开关的生效范围,从而避免配置表的样式影响系统界面(例如从业务 App 里打开的相册、通讯录、打印等系统界面)。 - 配置表增加
TabBarItemTitleFontSelected
用于设置选中状态的UITabBarItem
的字体。
会带来 QMUI 新旧版本兼容问题的更新
-[QMUINavigationController didInitialize]
被标记为废弃,将会在后续版本中被移除,请尽快将其替换为qmui_didInitialize
。- 废弃配置表的
ShouldFixTabBarButtonBugForAll
,改为强制自动修复 #410 描述的系统 bug,因为这种 bug 正常情况下没有“不希望被修复”的诉求。 - 修正
CALayer (QMUIViewAnimation). qmui_viewAnimationEnabled
拼写错误的问题。 - 将若干类方法的定义改为类属性(
@property (class)
),便于访问。 - 删除
- [UITabBarItem (QMUIConfiguration) qmui_updateTintColorForiOS12AndEarlier:]
方法。
如何适配新版
- 检查项目里继承自
QMUINavigationController
的所有子类是否有实现didInitialize
方法,有的话请将其替换为qmui_didInitialize
。 - 全局搜索“qmui_viewAnimaitonEnabled”,将其替换为“qmui_viewAnimationEnabled”。
- 全局搜索“qmui_updateTintColorForiOS12AndEarlier”,清理用到的地方。
- 如果你是 Swift 项目,类方法改为类属性可能会导致你的语法需要从
QMUIHelper.deviceName()
替换为QMUIHelper.deviceName
,由于数量众多,请遇到报错时自行修改。
如果有使用配置表
- 删除配置表的
ShouldFixTabBarButtonBugForAll
项。 - 将以下代码添加到配置表中并修改为希望的值:
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
- 修复
+[QMUIHelper safeAreaInsetsForDeviceWithNotch]
不准确的 bug。 - 修复
StatusBarHeightConstant
宏不准确的 bug。 - 修复
QMUICommonViewController
内置的QMUINavigationTitleView
无法响应UIViewController.navigationItem.title
的值的 bug。 - 修复 dismiss 到一个正在搜索的界面时,状态栏无法正确交给 UISearchController,而是错误地交给 searchController 背后的 vc 的 bug。
- 修复开启了配置表
NeedsBackBarButtonItemTitle
的情况下,业务自己设置的UIViewController.navigationItem.backBarButtonItem
会被强制覆盖的 bug。 - 修复 iOS 12 及以下的系统,通过
[UITabBarItem setTitleTextAttributes:forState:]
设置的 selected 字体无法生效的系统 bug(颜色可以生效,字体不行)。 - 修复开启了转场动画过程中 navigationBar 效果优化功能后,在转场动画过程中前后界面的样式发生变化,此时无法正确更新假 bar 的问题。
- #1087 修复使用了 QMUITheme 后,在 iOS 14 下首次升起键盘会触发 Main Thread Checker 警告的问题,4.2.1 里只是优化,4.2.2 里彻底修复。
- #1115 修复 QMUI 某些 description 可能触发 Main Thread Checker 的 bug。
- #1120 修复
QMUITextView
点击候选词触发最长字符数限制时,高度变化的回调newHeightAfterTextChanged
不会调用的 bug。 - #1122 修复
QMUITheme
在切换主题时无法刷新UITabBarItem.selectedImage
的 bug。 - #1130 修复配置表
NeedsBackBarButtonItemTitle
、backBarButtonItemTitleWithPreviousViewController:
与系统的backBarButtonItem
三者互相冲突的问题。 - #1148 修复
- [QMUIEmptyView sizeThatContentViewFits:]
高度计算错误的 bug。 - #1149 修复
QMUIZoomImageView
在 image/livePhoto/videoPlayerItem 三种内容之间切换时没有清空其他内容,导致缩放错误的 bug。 - #1150 修复
QMUIModalPresentationViewController
hide 时没有正确清空keyboardHeight
的 bug。 - #1156 修复
QMUICommonTableViewController
搭配 Storyboard 使用时 crash 的问题。 - #1163 修复
QMUIPieProgressView
使用约束布局时圆角有误的 bug。 - #1168 #1170 修复
QMUITextField
、QMUITextView
设置了maximumTextLength
后,在配合系统的三指粘贴/撤销快捷操作时可能引发 crash 的 bug。 - #1169 修复 iPad 12-inch 上一旦出现了
QMUIConsole
,界面上其他元素就无法点击的 bug。 - #1173 修复
QMUIKeyboardManager
无法兼容系统的“设置→辅助功能→动态效果→减弱动态效果→首选交叉淡出过渡效果”的问题。
其他
- 优化配置表
PreventConcurrentNavigationControllerTransitions
功能,在切换界面时如果上一次转场动画尚未结束,以前直接屏蔽本次切换,现改为将本次切换的 animated 置为 NO,既能避免 bug,又能允许界面正常切换。 - 优化
UIView (QMUI)
、UIImageView (QMUI)
内部若干 hook,将 hook 时机从 +load 改为按需。 - #1100 iOS 14.2 开始,系统已经修复了该问题,因此 QMUI 新版本里对 iOS 14.2 及以后的版本都屏蔽了相关代码。
4.2.1
新增功能
QMUISearchController
支持通过qmui_preferredStatusBarStyleBlock
控制进入搜索状态时的状态栏样式,不需要再在QMUISearchControllerDelegate
里记录、刷新状态栏了。UISearchBar(QMUI)
增加属性qmui_textFieldMarginsBlock
支持根据不同的active
状态设置不同的输入框 margin。UISearchBar(QMUI)
增加属性qmui_cancelButtonMarginsBlock
支持调整取消按钮 margin。- #1106
QMUICustomNavigationBarTransitionDelegate
增加方法shouldCustomizeNavigationBarTransitionIfUsingCustomTransitionForOperation:fromViewController:toViewController:
用于控制当业务实现了自己的转场动画时,是否还需要开启 QMUI 的 navigationBar 转场优化。旧版本在业务实现了自己的转场动画时,必定无法使用 navigationBar 转场优化。 QMUIHelper
增加+layerContentsGravityWithContentMode:
用于UIViewContentMode
和CALayerContentsGravity
之间的转换。UIControl(QMUI)
增加属性qmui_preventsRepeatedTouchUpInsideEvent
用于防止快速的重复点击。业务可以 swizzle UIControl 的 init,在里面统一开启某些指定控件的防重复点击(例如 QMUI Demo 默认开启了 UINavigationBar 上的按钮的防重复点击)。
会带来 QMUI 新旧版本兼容问题的更新
- 删除
QMUIUserInterfaceStyleWillChangeNotification
,改为用+[UITraitCollection qmui_addUserInterfaceStyleWillChangeObserver:selector:]
监听系统的 Dark Mode 切换,从而优化 #1087 (#1045 #1059 #1080) 提的 iOS 14 下首次升起键盘时会命中 Main Thread Checker 警告的问题,优化后只有用了QMUITheme
组件的才会命中警告(原理上无法避免,仅对开发过程有影响,不影响发布版 App)。 - 配置表
StatusbarStyleLightInitially
开关以前只能对QMUICommnoViewController
及其子类生效,现在对QMUITabBarViewController
、QMUINavigationController
的所有 childViewController 都可以生效,不管该 childViewController 父类是什么。 - 将
UIImageView(QMUI).qmui_smoothAnimation
的默认值从YES
改为NO
,因为实测目前系统在UIScrollView
里用UIImageView
展示 GIF 已经没有什么性能问题。 - 去掉代码里所有的
#ifdef IOS13_SDK_ALLOWED
判断。
如何适配新版
- 全局搜索“QMUIUserInterfaceStyleWillChangeNotification”,将其改为用新的
+[UITraitCollection qmui_addUserInterfaceStyleWillChangeObserver:selector:]
。 - 检查在
QMUITabBarViewController
、QMUINavigationController
里展示的非QMUICommonViewController
子类的 viewController 的状态显示是否正常。 - 检查业务项目里使用
qmui_smoothAnimation
展示 GIF 的场景是否还正常。 - 请勿使用低于 Xcode 11 的版本进行开发。
如果有使用配置表
Bugfix
- #888 修复
-[QMUITableViewCell layoutSubviews]
里对textLabel
布局的手误写法。 - #809 #898 修复设置了
overrideUserInterfaceStyle
后启动 App 会死循环的 bug。 - #983 修复
QMUIModalPresentationViewController
在调用 show 后无法立马通过 hide 隐藏浮层的 bug。 - #1065 修复
QMUIPieProgressView
绘制环形时报警告“CGContextClosePath: no current point.” 的 bug。 - #1066 修复
QMUINavigationTitleView
subAccessoryView
布局错误的 bug。 - #1071 修复
UIImageView(QMUI).qmui_smoothAnimation = YES
时修改contentMode
无效的 bug。 - #1073 修复
CALayer(QMUI).qmui_maskedCorners
无法对独立的CALayer
生效,只能作用于UIView.layer
的问题。 - #1074 修复
CALayer(QMUI).qmui_maskedCorners
无法在子线程中使用,会触发 UIView layoutSublayersOfLayer: 导致命中 NSAssert 的问题。 - #1079 去掉
UIView(QMUI)
内对convertRect
系列的坐标系检测,去掉addSubview:
对“把 self add 到 self 上”的检测。 - #1081 #1107 修复 iOS 14 开启
customNavigationBarTransitionKey
的情况下转场效果错误,bar 透明的 bug。 - #1090 修复单独 pod QMUIImagePickerLibrary 无法正确拿到 QMUIResources 图片的 bug。
- #1094 修复某些场景下
UINavigationController(QMUI).qmui_isPushing
可能遇到数组越界的 bug。 - #1096 修复
QMUIBadge
可能出现未读数字宽度小于高度的 bug。 - #1100 修复 iOS 14 pop 到一个
hidesBottomBarWhenPushed = NO
的界面后UITabBar
无法正确显示出来的系统 bug。 - #1105 修复
QMUITextView
粘贴文字时如果受到maximumTextLength
限制时无法自动裁剪的 bug。 - #1110 修复 iOS 14 修改
UITabBarAppearance.inlineLayoutAppearance.normal.titleTextAttributes[NSForegroundColorAttributeName]
会导致 UITabBarItem 文字无法完整展示的 bug。 - 修复
QMUINavigationController
里对状态栏样式管理的 bug。 - 修复开启 BoldText 后同时显示文字+图片的
QMUIButton
文字无法完整展示的 bug。 - 修复
+[UIImage(QMUI) qmui_animatedImageWithData:scale:]
在传入的 data 只有一张图的情况下无法通过参数scale
指定图片倍数的 bug。 - 修复
-[UINavigationController(QMUI) qmui_pushViewController:animated:completion:]
系列方法的completion
实际上会立马被调用的 bug。 - 修复
QMUICommonTableViewController
description
里的循环调用。
其他
- #1091 使用二分查找法优化查找 view 所在 section 的过程 by @MaxwellLeeee 。
QMUIThemeImage
里的消息转发兼容OpenCV
。- 移除
+[QMUIHelper executeAnimationBlock:completionBlock:]
注释里对支持 UINavigationController 转场动画的说明。 - 优化 QMUIKit 若干在
+load
里的 method swizzling,改为在用到相应功能时才进行 swizzle。
4.2.0
由于 iOS 14 Beta 的发布,QMUI 从这个版本开始将不再支持 iOS 9。
新增功能
- 增加
QMUITableViewStyleInsetGrouped
组件用于支持全 iOS 版本的 InsetGrouped 类型的列表,示例代码请查看 QMUI Demo→QMUIKit→QMUITableView→QMUITableViewStyleInsetGrouped。 - 配置表增加
TableViewGroupedSeparatorColor
用于控制UITableViewStyleGrouped
类型的列表分隔线颜色。 - #1015
QMUIAlertController
增加alertTextFieldTextInsets
、alertTextFieldMarginBlock
属性用于调整输入框的大小和布局。 QMUIPopupContainerView
增加arrowImage
属性支持用一张图来作为浮层的箭头。QMUIStaticTableViewCellData
增加didSelectBlock
,支持以 block 的形式处理 cell 点击事件(以前只能使用 target-action 模式);增加accessoryBlock
,支持以 block 的形式处理accessoryView
点击事件(以前只能使用 target-action 模式)。UIColor(QMUI)
增加qmui_colorWithRGBAString:
方法用于将一个 RGBA 字符串转换成UIColor
对象。UIView(QMUI)
增加qmui_sizeThatFitsBlock
属性便于重写sizeThatFits:
。- 增加
UIVisualEffectView(QMUI)
组件,提供qmui_foregroundColor
属性让你可以去掉系统自带的前景色的同时设置自己的前景色,从而保证更准确的设计效果。系统的UIVisualEffectView
在不同的 style 下会带有不同的前景色。 UITableView(QMUI)
增加qmui_validContentWidth
属性用于获取当前列表用于呈现内容的区域的宽度,例如全面屏设备下会减去 safeAreaInsets.left/right,InsetGrouped 样式下会减去左右的缩进。UITableViewCell(QMUI)
增加以下特性:- 增加
qmui_style
属性用于获取初始化 cell 时指定的UITableViewCellStyle
。 - 增加
qmui_cellPosition
属性用于在willDisplayCell
及以后的时机里能获取当前 cell 在 section 里的位置,如果是在cellForRow
里则依然只能自己通过-[UITableView qmui_positionForRowAtIndexPath:]
计算,无法使用qmui_cellPosition
。 - 增加
qmui_separatorInsetsBlock
、qmui_topSeparatorInsetsBlock
用于控制 cell 的分隔线位置,由于 block 是渲染时才会调用,所以你可以在 block 里方便地根据当前 tableView 的 style、cell 的 position、cell 的 subviews 的布局来设置分隔线位置,这是系统自带的分隔线无法做到的事情。你可以在业务项目里 swizzleUITableViewCell
的 init 方法,在里面统一设置全局分隔线的逻辑,就无需每个 cell 子类都调整一次。
- 增加
UISearchBar(QMUI)
增加以下特性,对应地 QMUI Demo 也增加新的示例界面:QMUIKit→UISearchBar+QMUI→UISearchBar(QMUI)
- 增加
qmui_centerPlaceholder
用于让 iOS 11 及以后的搜索框 placeholder 也能默认居中(系统默认是居左)。 - 增加
qmui_leftAccessoryView
、qmui_rightAccessoryView
支持在输入框左右各显示一个 view,从而你可以方便地添加自己的按钮(例如在搜索框左边显示一个返回按钮,在右边显示一个结果过滤、结果排序按钮等)。
- 增加
QMUIHelper
增加executeBlock: oncePerIdentifier:
用于令某段逻辑只被执行一次,QMUIKit 中通常用来避免重复 swizzle 相同方法。QMUICommonDefines.h
增加IOS14_SDK_ALLOWED
用于识别当前是 iOS 14 SDK 编译环境。- 让
UINavigationBar
、UITabBar
在没设置backgroundImage
时也能正确显示shadowImage
(系统默认行为是只有设置了backgroundImage
后shadowImage
才能生效),从而保证不同 iOS 系统里的表现一致。 - 感谢 @MaxwellLeeee 增加对
QMUIToastAnimator
里 Zoom 和 Slide 两种动画方式的支持。
会带来 QMUI 新旧版本兼容问题的更新
- 最低支持版本从 iOS 9.0 升级为 iOS 10.0。
- 重构
QMUIBadge
未读数组件,原本仅支持在UIBarItem
上显示未读数/未读红点,现在可以在任意的UIView
上显示未读数/未读红点了。同时为了优化使用体验,将原本基于中心布局的qmui_badgeCenterOffset
、qmui_badgeCenterOffsetLandscape
、qmui_updatesIndicatorCenterOffset
、qmui_updatesIndicatorCenterOffsetLandscape
4个属性标记为废弃,新组件将基于右上角布局,使用新属性qmui_badgeOffset
、qmui_badgeOffsetLandscape
、qmui_updatesIndicatorOffset
、qmui_updatesIndicatorOffsetLandscape
代替以前的4个旧属性。同时 QMUI Demo 里也增加了对应的示例代码。 - 对于
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;
。
如何适配新版
- 全局搜索“qmui_badgeCenterOffset”,改为用
qmui_badgeOffset
,具体值要自行调整。 - 全局搜索“qmui_badgeCenterOffsetLandscape”,改为用
qmui_badgeOffsetLandscape
,具体值要自行调整。 - 全局搜索“qmui_updatesIndicatorCenterOffset”,改为用
qmui_updatesIndicatorOffset
,具体值要自行调整。 - 全局搜索“qmui_updatesIndicatorCenterOffsetLandscape”,改为用
qmui_updatesIndicatorOffsetLandscape
,具体值要自行调整。 - 全局搜索“BadgeCenterOffset”,改为用
BadgeOffset
。 - 全局搜索“BadgeCenterOffsetLandscape”,改为用
BadgeOffsetLandscape
。 - 全局搜索“UpdatesIndicatorCenterOffset”,改为用
UpdatesIndicatorOffset
。 - 全局搜索“UpdatesIndicatorCenterOffsetLandscape”,改为用
UpdatesIndicatorOffsetLandscape
。 - 全局搜索对
QMUIAlertController.dismissKeyboardAutomatically
的使用,由于不支持 iOS 9,所以这个属性已经没用了,请删除。
如果有使用配置表
- 将以下代码添加到配置表里:
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
- 将以下设置项从配置表里删除:
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
- #997 修复输入框聚焦并升起键盘的情况下,App 进入后台再回到前台,键盘外观会错误的 bug。
- #1001 修复在 Mac Catalyst 里调用
+[UIImage qmui_imageWithThemeProvider]
会死循环的 bug。 - #1012 修复
QMUIPopupMenuButtonItem
内的QMUIButton.imageView
可能出现负值的bounds
,导致一些布局错误的 bug。 - #1026 修复 iOS 12 及以下,
UITabBarItem
只设置image
没设置selectedImage
时,无法通过配置表设置图片颜色的 bug。 - #1037 修复
QMUIToast
修改内容后布局没有刷新的 bug。 - #1042 修复 iOS 14 下切换到 emoji 键盘会 crash 的 bug。
- #1048 修复 `-[QMUIZoomImageView showEmptyViewWithText] 无法显示 emptyView 的 bug...
4.1.3
4.1.2
新增功能
- 新增
CALayer (QMUIViewAnimation)
,让CALayer
可以在+[UIView animateWithDuration:animations:]
内直接写动画代码。 UIImage(QMUI)
增加属性qmui_resizable
用于区分当前是否为 resize 处理过的图片。UINavigationBar(QMUI)
增加属性qmui_contentView
用于获取导航栏内部的 contentView。UISearchBar(QMUI)
增加属性qmui_fixMaskViewLayoutBugAutomatically
用于控制是否要自动修复 #950 的系统 bug,默认不修复。+[QMUIHelper deviceName]
补齐新发布的设备。
会带来 QMUI 新旧版本兼容问题的更新
- 以更彻底的方式修复系统在某些场景下
UITabBar
的布局 bug,同时修改了配置表ShouldFixTabBarSafeAreaInsetsBugForNotchedScreen
的命名,具体适配操作请查看如何适配新版。 - 之前某些组件为了方便,在
init
时就用loadViewIfNeeded
触发viewDidLoad
来初始化 subviews,然而这会导致继承了这些组件的子类写在init
里的业务逻辑的调用时机比写在viewDidLoad
里的调用时机还晚,可能引发一些非预期的问题,所以这个版本我们去掉了这种做法,理论上是无感知的改动,安全起见建议按 如何适配新版 进行检查。
如何适配新版
- 请检查项目里相关组件的使用是否正常,包括这些组件的子类的使用:
- QMUIAlertController
- QMUIImagePickerViewController
- QMUIImagePreviewViewController
- QMUIMoreOperationController
- QMUIConsoleViewController
- 如果有使用配置表,请搜索“shouldFixTabBarSafeAreaInsetsBugForNotchedScreen”,将其重命名为“ shouldFixTabBarSafeAreaInsetsBug”。
- 如果有使用配置表,请将以下代码添加到配置表并设置为希望的值:
QMUICMI.windowLevelQMUIConsole = 1; // UIWindowLevelQMUIConsole : QMUIConsole 内部的 UIWindow 的 windowLevel
QMUICMI.shouldFixSearchBarMaskViewLayoutBug = NO; // ShouldFixSearchBarMaskViewLayoutBug : 是否自动修复 UISearchController.searchBar 被当作 tableHeaderView 使用时可能出现的布局 bug(issue #950)
Bugfix
- #218 #934 以更彻底的方式修复系统
UITabBar
在若干情况下的各种布局 bug。 - #949 修复
QMUIPopupContainerView
在指定方向空间不足的情况下无法自动切换到反向显示 bug。 - #950 修复当
UISearchController.searchBar
作为tableHeaderView
使用时,顶部可能出现 1px 的间隙导致露出背景色的系统 bug。 - #952 修复
shouldPopViewControllerByBackButtonOrPopGesture:
在某些情况下传入的参数错误的 bug。 - #968 修复
QMUIConsole
在application:didFinishLaunchingWithOptions:
里 App 主UIWindow
尚未显示前就调用时无法显示的 bug。 - #970 修复
QMUITextView
与 ReactiveObjC 搭配使用时会死循环的 bug。 - #971 修复 iOS 12 及以下版本,
QMUIThemeImage
在搭配 resizable 使用的情况下可能无法跟随主题刷新的 bug。 - #974 修复
-[QMUICellHeightCache qmui_invalidateHeightForKey:]
无效的 bug。 - #975 修复 iOS 9 下
QMUIAlertController
无法显示的 bug。 - 修复 iOS 9 下调用
qmui_applyAppearance
会提前触发viewDidLoad
的问题。 - 修复
QMUIModalPresentationViewController
在showInView
的情况下 show animated:YES 但 hide animated:NO 时会无法隐藏浮层的 bug。 - 保护
QMUIModalPresentationViewController
在快速 show/hide 时会错乱的问题。 - 修复
-[UIImage(QMUI) qmui_imageWithTintColor:]
在用半透明颜色处理一张不透明的图片时,最终输出的图片依然是不透明的,导致颜色处理错误的 bug。
4.1.1
会带来 QMUI 新旧版本兼容问题的更新
- #939 调整配置表
NavBarShadowImage
和NavBarShadowImageColor
的作用,具体请查看 issue 内容。
如何适配新版
- 如果有使用配置表,请检查 App 运行后
NavBarShadowImage
和NavBarShadowImageColor
的表现是否正确。
Bugfix
4.1.0
新增功能
- 增加
QMUIAppearance
组件用于让非UIView
的NSObject
子类也可以使用UIAppearance
能力,并将项目里相关组件都改为用QMUIAppearance
:ImagePickerLibrary
、QMUIAlertController
、QMUIDialogViewController
、QMUIImagePreviewViewController
、QMUIModalPresentationViewController
、QMUIMoreOperationController
。 - 增加
NSObject (QMUIAppearnace)
,提供方法-qmui_applyAppearance
用于将当前 Class 的 appearance 应用到当前实例上,该方法支持UIView
和非UIView
的任意对象。 NSObject (QMUI)
增加qmui_canGetValueForKey:
、qmui_canSetValueForKey:
用于判断某个给定的 key 是否可以用于当前对象的 KVC。- #920
UINavigationController (QMU)
增加属性qmui_interactivePopGestureRecognizerDelegate
用于获取系统原始的interactivePopGestureRecognizer.delegate
的值。 UIViewController (QMUI)
增加属性qmui_prefersStatusBarHiddenBlock
、qmui_preferredStatusBarStyleBlock
、qmui_preferredStatusBarUpdateAnimationBlock
、qmui_prefersHomeIndicatorAutoHiddenBlock
便于在非继承的情况下依然能控制界面状态栏、Home Indicator。QMUIAlertController
增加属性sheetButtonColumnCount
支持一行显示多个按钮。QMUIModalPresentationViewController
新增willHideByDimmingViewTappedBlock
属性用于监听浮层即将被隐藏的时机。QMUIRuntime
增加qmui_getProjectClassList()
函数用于获取业务项目的 Class 列表(不包含系统 Class 和引入的第三方 Framework)。QMUIOrderedDictionary
支持下标的语法操作。- #691
QMUIPopupContainerView
增加QMUIPopupContainerViewLayoutDirectionLeft
、QMUIPopupContainerViewLayoutDirectionRight
以支持水平方向的展示,QMUI Demo 也更新了展示示例。 QMUIPopupContainerView
支持用contentMode
切换内置图片、文本的布局方式。- 配置表增加
TextFieldTextColor
用于全局设置QMUITextField
、QMUITextView
的textColor
,对UITextField
、UITextView
不影响。
会带来 QMUI 新旧版本兼容问题的更新
- 将 4.0.0-beta 就标记为已废弃的方法
shouldHoldBackButtonEvent
、canPopViewController
删除。
如何适配新版
- 全局 Matching Word 搜索“shouldHoldBackButtonEvent”、“canPopViewController”,将用到的地方改为新的方法“ shouldPopViewControllerByBackButtonOrPopGesture”。
- 如果有使用配置表,请将以下代码添加到配置表:
QMUICMI.textFieldTextColor = nil; // TextFieldTextColor : QMUITextField、QMUITextView 的 textColor,不影响 UIKit 的输入框
QMUICMI.shouldFixTabBarSafeAreaInsetsBugForNotchedScreen = NO; // ShouldFixTabBarSafeAreaInsetsBugForNotchedScreen : 是否要对 iOS 11 及以后的版本修复全面屏设备下 pop 界面时 UIScrollView 的 inset 会跳动导致滚动位置受影响的 bug(issue #934),默认为 NO
Bugfix
- #884 修复某些
UIModalPresentationStyle
情况下,present 起来的 viewController 无法响应 QMUITheme 切换的 bug。 - #900 修复
QMUIPieProgressView
在以动画的形式修改progress
过程中borderInset
失效的 bug。 - #906 修复
QMUICommonTableViewController
可能出现提前触发loadView
的 bug。 - #914 优化配置表里对
StatusbarStyleLightInitially
的注释。 - #923 修复
QMUITheme
会强制用配置表的KeyboardAppearance
值覆盖业务的值,导致某些界面如果想要与全局统一的键盘外观不一致,则无法实现的 bug。 - #930 修复与
DoraemonKit
冲突引发dispatch_once
死锁的问题。 - #934 修复全面屏设备下,带
UITabBar
的界面在 push/pop 后,UIScrollView 的滚动位置可能发生变化的系统 bug,但默认代码是屏蔽的,需要手动将配置表里的ShouldFixTabBarSafeAreaInsetsBugForNotchedScreen
置为YES
才可以,具体请看如何适配新版。 - 修复
QMUICollectionViewPagingLayout
在某些时候滑动时会滚动到错误 item 的 bug。 - 修复
QMUIImagePreviewView
在快速滚动时某些 index 的imagePreviewView:willScrollHalfToIndex:
可能没有被触发的问题。 - 修复
QMUIFloatLayoutView.itemMargins.top
不生效的 bug。 - 修复
QMUIModalPresentationViewController
如果使用contentViewController
的情况下无法重复 show 的问题。 - 修复
QMUIModalPresentationViewController
如果使用contentViewController
的情况下,在调用 show 之前无法获取到qmui_modalPresentationViewController
的问题。 - 修复
QMUIMultipleDelegates
无法使用valueForKey:
、setValue:forKey:
的问题。 - 修复 iOS 13.4 下 UINavigationController 可能出现手势返回异常的情况。