Skip to content

Commit 09cdc05

Browse files
author
molicechen
committed
4.2.1
1 parent f5e04da commit 09cdc05

57 files changed

Lines changed: 1004 additions & 738 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

QMUIConfigurationTemplate/QMUIConfigurationTemplate.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ - (void)applyConfigurationTemplate {
258258
QMUICMI.automaticCustomNavigationBarTransitionStyle = NO; // AutomaticCustomNavigationBarTransitionStyle : 界面 push/pop 时是否要自动根据两个界面的 barTintColor/backgroundImage/shadowImage 的样式差异来决定是否使用自定义的导航栏效果
259259
QMUICMI.supportedOrientationMask = UIInterfaceOrientationMaskAll; // SupportedOrientationMask : 默认支持的横竖屏方向
260260
QMUICMI.automaticallyRotateDeviceOrientation = NO; // AutomaticallyRotateDeviceOrientation : 是否在界面切换或 viewController.supportedOrientationMask 发生变化时自动旋转屏幕
261-
QMUICMI.statusbarStyleLightInitially = NO; // StatusbarStyleLightInitially : 默认的状态栏内容是否使用白色,默认为 NO,在 iOS 13 下会自动根据是否 Dark Mode 而切换样式,iOS 12 及以前则为黑色
261+
QMUICMI.statusbarStyleLightInitially = NO; // StatusbarStyleLightInitially : 默认的状态栏内容是否使用白色,默认为 NO,在 iOS 13 下会自动根据是否 Dark Mode 而切换样式,iOS 12 及以前则为黑色。生效范围:处于 QMUITabBarController 或 QMUINavigationController 内的 vc,或者 QMUICommonViewController 及其子类。
262262
QMUICMI.needsBackBarButtonItemTitle = YES; // NeedsBackBarButtonItemTitle : 全局是否需要返回按钮的 title,不需要则只显示一个返回image
263263
QMUICMI.hidesBottomBarWhenPushedInitially = NO; // HidesBottomBarWhenPushedInitially : QMUICommonViewController.hidesBottomBarWhenPushed 的初始值,默认为 NO,以保持与系统默认值一致,但通常建议改为 YES,因为一般只有 tabBar 首页那几个界面要求为 NO
264264
QMUICMI.preventConcurrentNavigationControllerTransitions = YES; // PreventConcurrentNavigationControllerTransitions : 自动保护 QMUINavigationController 在上一次 push/pop 尚未结束的时候就进行下一次 push/pop 的行为,避免产生 crash

QMUIKit.podspec

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = "QMUIKit"
3-
s.version = "4.2.0"
3+
s.version = "4.2.1"
44
s.summary = "致力于提高项目 UI 开发效率的解决方案"
55
s.description = <<-DESC
66
QMUI iOS 是一个致力于提高项目 UI 开发效率的解决方案,其设计目的是用于辅助快速搭建一个具备基本设计还原效果的 iOS 项目,同时利用自身提供的丰富控件及兼容处理, 让开发者能专注于业务需求而无需耗费精力在基础代码的设计上。不管是新项目的创建,或是已有项目的维护,均可使开发效率和项目质量得到大幅度提升。
@@ -10,6 +10,7 @@ Pod::Spec.new do |s|
1010
s.author = {"qmuiteam" => "contact@qmuiteam.com"}
1111
s.source = {:git => "https://github.com/Tencent/QMUI_iOS.git", :tag => s.version.to_s}
1212
#s.source = {:git => "https://github.com/Tencent/QMUI_iOS.git", :branch => 'master'}
13+
#s.source = {:path => "./"}
1314
s.social_media_url = 'https://github.com/Tencent/QMUI_iOS'
1415
s.requires_arc = true
1516
s.documentation_url = 'https://qmuiteam.com/ios/page/document.html'
@@ -19,7 +20,6 @@ Pod::Spec.new do |s|
1920
s.frameworks = 'Foundation', 'UIKit', 'CoreGraphics'
2021
s.preserve_paths = 'QMUIConfigurationTemplate/*'
2122
s.source_files = 'QMUIKit/QMUIKit.h'
22-
s.resource_bundles = {'QMUIResources' => ['QMUIKit/QMUIResources/*.*']}
2323

2424
s.subspec 'QMUICore' do |ss|
2525
ss.source_files = 'QMUIKit/QMUIKit.h', 'QMUIKit/QMUICore', 'QMUIKit/UIKitExtensions'
@@ -39,6 +39,10 @@ Pod::Spec.new do |s|
3939
ss.dependency 'QMUIKit/QMUIComponents/QMUIMultipleDelegates'
4040
end
4141

42+
s.subspec 'QMUIResources' do |ss|
43+
ss.resource_bundles = {'QMUIResources' => ['QMUIKit/QMUIResources/*.*']}
44+
end
45+
4246
s.subspec 'QMUIWeakObjectContainer' do |ss|
4347
ss.source_files = 'QMUIKit/QMUIComponents/QMUIWeakObjectContainer.{h,m}'
4448
end
@@ -160,6 +164,7 @@ Pod::Spec.new do |s|
160164

161165
ss.subspec 'QMUIConsole' do |sss|
162166
sss.source_files = 'QMUIKit/QMUIComponents/QMUIConsole/*.{h,m}'
167+
sss.dependency 'QMUIKit/QMUIResources'
163168
sss.dependency 'QMUIKit/QMUIComponents/QMUITextView'
164169
sss.dependency 'QMUIKit/QMUIComponents/QMUITextField'
165170
sss.dependency 'QMUIKit/QMUIComponents/QMUIButton'
@@ -186,6 +191,7 @@ Pod::Spec.new do |s|
186191

187192
ss.subspec 'QMUIEmotionView' do |sss|
188193
sss.source_files = 'QMUIKit/QMUIComponents/QMUIEmotionView.{h,m}'
194+
sss.dependency 'QMUIKit/QMUIResources'
189195
sss.dependency 'QMUIKit/QMUIComponents/QMUIButton'
190196
end
191197

@@ -325,6 +331,7 @@ Pod::Spec.new do |s|
325331

326332
ss.subspec 'QMUITips' do |sss|
327333
sss.source_files = 'QMUIKit/QMUIComponents/QMUITips.{h,m}'
334+
sss.dependency 'QMUIKit/QMUIResources'
328335
sss.dependency 'QMUIKit/QMUIComponents/QMUIToastView'
329336
end
330337

@@ -339,6 +346,7 @@ Pod::Spec.new do |s|
339346

340347
ss.subspec 'QMUIZoomImageView' do |sss|
341348
sss.source_files = 'QMUIKit/QMUIComponents/QMUIZoomImageView.{h,m}'
349+
sss.dependency 'QMUIKit/QMUIResources'
342350
sss.dependency 'QMUIKit/QMUIComponents/QMUIEmptyView'
343351
sss.dependency 'QMUIKit/QMUIComponents/QMUIButton'
344352
sss.dependency 'QMUIKit/QMUIComponents/QMUISlider'
@@ -354,6 +362,7 @@ Pod::Spec.new do |s|
354362
ss.subspec 'QMUIImagePickerLibrary' do |sss|
355363
sss.source_files = 'QMUIKit/QMUIComponents/ImagePickerLibrary/*.{h,m}'
356364
sss.dependency 'QMUIKit/QMUIMainFrame'
365+
sss.dependency 'QMUIKit/QMUIResources'
357366
sss.dependency 'QMUIKit/QMUIComponents/QMUIImagePreviewView'
358367
sss.dependency 'QMUIKit/QMUIComponents/QMUITableViewCell'
359368
sss.dependency 'QMUIKit/QMUIComponents/QMUIButton'

QMUIKit/QMUIComponents/NavigationBarTransition/UINavigationController+NavigationBarTransition.m

Lines changed: 68 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,32 @@ @interface _QMUITransitionNavigationBar : UINavigationBar
3333

3434
@implementation _QMUITransitionNavigationBar
3535

36+
+ (void)load {
37+
static dispatch_once_t onceToken;
38+
dispatch_once(&onceToken, ^{
39+
// TODO: molice iOS 14 正式版发布后检查
40+
// iOS 14 Beta 6 开启 customNavigationBarTransitionKey 的情况下转场效果错误
41+
// https://github.com/Tencent/QMUI_iOS/issues/1081
42+
if (@available(iOS 14.0, *)) {
43+
OverrideImplementation([_QMUITransitionNavigationBar class], NSSelectorFromString([NSString stringWithFormat:@"_%@_%@", @"accessibility", @"navigationController"]), ^id(__unsafe_unretained Class originClass, SEL originCMD, IMP (^originalIMPProvider)(void)) {
44+
return ^UINavigationController *(_QMUITransitionNavigationBar *selfObject) {
45+
if (selfObject.originalNavigationBar) {
46+
BeginIgnorePerformSelectorLeaksWarning
47+
return [selfObject.originalNavigationBar performSelector:originCMD];
48+
EndIgnorePerformSelectorLeaksWarning
49+
}
50+
51+
// call super
52+
UINavigationController *(*originSelectorIMP)(id, SEL);
53+
originSelectorIMP = (UINavigationController *(*)(id, SEL))originalIMPProvider();
54+
UINavigationController *result = originSelectorIMP(selfObject, originCMD);
55+
return result;
56+
};
57+
});
58+
}
59+
});
60+
}
61+
3662
- (void)setOriginalNavigationBar:(UINavigationBar *)originBar {
3763
_originalNavigationBar = originBar;
3864

@@ -208,40 +234,34 @@ + (void)load {
208234

209235
OverrideImplementation([UIViewController class], @selector(viewWillLayoutSubviews), ^id(__unsafe_unretained Class originClass, SEL originCMD, IMP (^originalIMPProvider)(void)) {
210236
return ^(UIViewController *selfObject) {
237+
id<UIViewControllerTransitionCoordinator> transitionCoordinator = selfObject.transitionCoordinator;
238+
UIViewController *fromViewController = [transitionCoordinator viewControllerForKey:UITransitionContextFromViewControllerKey];
239+
UIViewController *toViewController = [transitionCoordinator viewControllerForKey:UITransitionContextToViewControllerKey];
211240

212-
if (selfObject.navigationController.delegate && ![selfObject.navigationController.delegate respondsToSelector:@selector(navigationController:animationControllerForOperation:fromViewController:toViewController:)]) {
213-
214-
id<UIViewControllerTransitionCoordinator> transitionCoordinator = selfObject.transitionCoordinator;
215-
UIViewController *fromViewController = [transitionCoordinator viewControllerForKey:UITransitionContextFromViewControllerKey];
216-
UIViewController *toViewController = [transitionCoordinator viewControllerForKey:UITransitionContextToViewControllerKey];
241+
BOOL isCurrentToViewController = (selfObject == selfObject.navigationController.viewControllers.lastObject && selfObject == toViewController);
242+
243+
if (isCurrentToViewController && !selfObject.lockTransitionNavigationBar) {
217244

218-
BOOL isCurrentToViewController = (selfObject == selfObject.navigationController.viewControllers.lastObject && selfObject == toViewController);
245+
BOOL shouldCustomNavigationBarTransition = NO;
219246

220-
if (isCurrentToViewController && !selfObject.lockTransitionNavigationBar) {
221-
222-
BOOL shouldCustomNavigationBarTransition = NO;
223-
224-
if (!selfObject.transitionNavigationBar) {
225-
226-
if ([selfObject shouldCustomTransitionAutomaticallyWithFirstViewController:fromViewController secondViewController:toViewController]) {
227-
shouldCustomNavigationBarTransition = YES;
228-
}
229-
230-
if (shouldCustomNavigationBarTransition) {
231-
if (selfObject.navigationController.navigationBar.translucent) {
232-
// 如果原生bar是半透明的,需要给containerView加个背景色,否则有可能会看到下面的默认黑色背景色
233-
toViewController.originContainerViewBackgroundColor = [transitionCoordinator containerView].backgroundColor;
234-
[transitionCoordinator containerView].backgroundColor = [selfObject containerViewBackgroundColor];
235-
}
236-
[selfObject addTransitionNavigationBarIfNeeded];
237-
[selfObject resizeTransitionNavigationBarFrame];
238-
selfObject.navigationController.navigationBar.transitionNavigationBar = selfObject.transitionNavigationBar;
239-
selfObject.prefersNavigationBarBackgroundViewHidden = YES;
247+
if (!selfObject.transitionNavigationBar) {
248+
UINavigationControllerOperation operation = toViewController.navigationController.topViewController == toViewController ? UINavigationControllerOperationPush: UINavigationControllerOperationPop;
249+
if ([selfObject shouldCustomTransitionAutomaticallyForOperation:operation firstViewController:fromViewController secondViewController:toViewController]) {
250+
shouldCustomNavigationBarTransition = YES;
251+
}
252+
if (shouldCustomNavigationBarTransition) {
253+
if (selfObject.navigationController.navigationBar.translucent) {
254+
// 如果原生bar是半透明的,需要给containerView加个背景色,否则有可能会看到下面的默认黑色背景色
255+
toViewController.originContainerViewBackgroundColor = [transitionCoordinator containerView].backgroundColor;
256+
[transitionCoordinator containerView].backgroundColor = [selfObject containerViewBackgroundColor];
240257
}
258+
[selfObject addTransitionNavigationBarIfNeeded];
259+
[selfObject resizeTransitionNavigationBarFrame];
260+
selfObject.navigationController.navigationBar.transitionNavigationBar = selfObject.transitionNavigationBar;
261+
selfObject.prefersNavigationBarBackgroundViewHidden = YES;
241262
}
242263
}
243264
}
244-
245265
// call super
246266
void (*originSelectorIMP)(id, SEL);
247267
originSelectorIMP = (void (*)(id, SEL))originalIMPProvider();
@@ -443,7 +463,7 @@ - (BOOL)hideNavigationBarWhenTransitioning {
443463
return NO;
444464
}
445465

446-
- (BOOL)shouldCustomTransitionAutomaticallyWithFirstViewController:(UIViewController *)viewController1 secondViewController:(UIViewController *)viewController2 {
466+
- (BOOL)shouldCustomTransitionAutomaticallyForOperation:(UINavigationControllerOperation)operation firstViewController:(UIViewController *)viewController1 secondViewController:(UIViewController *)viewController2 {
447467

448468
UIViewController<QMUINavigationControllerDelegate> *vc1 = (UIViewController<QMUINavigationControllerDelegate> *)viewController1;
449469
UIViewController<QMUINavigationControllerDelegate> *vc2 = (UIViewController<QMUINavigationControllerDelegate> *)viewController2;
@@ -452,6 +472,15 @@ - (BOOL)shouldCustomTransitionAutomaticallyWithFirstViewController:(UIViewContro
452472
return NO;// 只处理前后两个界面都是 QMUI 系列的场景
453473
}
454474

475+
if ([vc1.navigationController.delegate respondsToSelector:@selector(navigationController:animationControllerForOperation:fromViewController:toViewController:)]) {
476+
// 说明可能有自定义的系统转场动画
477+
BOOL a = [vc1 respondsToSelector:@selector(shouldCustomizeNavigationBarTransitionIfUsingCustomTransitionForOperation:fromViewController:toViewController:)] ? [vc1 shouldCustomizeNavigationBarTransitionIfUsingCustomTransitionForOperation:operation fromViewController:vc1 toViewController:vc2] : NO;
478+
BOOL b = [vc2 respondsToSelector:@selector(shouldCustomizeNavigationBarTransitionIfUsingCustomTransitionForOperation:fromViewController:toViewController:)] ? [vc2 shouldCustomizeNavigationBarTransitionIfUsingCustomTransitionForOperation:operation fromViewController:vc1 toViewController:vc2] : NO;
479+
if (!a && !b) {
480+
return NO;
481+
}
482+
}
483+
455484
if ([vc1 respondsToSelector:@selector(customNavigationBarTransitionKey)] || [vc2 respondsToSelector:@selector(customNavigationBarTransitionKey)]) {
456485
NSString *key1 = [vc1 respondsToSelector:@selector(customNavigationBarTransitionKey)] ? [vc1 customNavigationBarTransitionKey] : nil;
457486
NSString *key2 = [vc2 respondsToSelector:@selector(customNavigationBarTransitionKey)] ? [vc2 customNavigationBarTransitionKey] : nil;
@@ -463,6 +492,8 @@ - (BOOL)shouldCustomTransitionAutomaticallyWithFirstViewController:(UIViewContro
463492
return NO;
464493
}
465494

495+
496+
466497
UIImage *bg1 = [vc1 respondsToSelector:@selector(navigationBarBackgroundImage)] ? [vc1 navigationBarBackgroundImage] : [[UINavigationBar appearance] backgroundImageForBarMetrics:UIBarMetricsDefault];
467498
UIImage *bg2 = [vc2 respondsToSelector:@selector(navigationBarBackgroundImage)] ? [vc2 navigationBarBackgroundImage] : [[UINavigationBar appearance] backgroundImageForBarMetrics:UIBarMetricsDefault];
468499
if (bg1 || bg2) {
@@ -559,19 +590,14 @@ + (void)load {
559590
originSelectorIMP(selfObject, originCMD, aViewController, aAnimated);
560591
};
561592

562-
if ([selfObject.delegate respondsToSelector:@selector(navigationController:animationControllerForOperation:fromViewController:toViewController:)]) {
563-
callSuperBlock(viewController, animated);
564-
return;
565-
}
566-
567593
UIViewController *disappearingViewController = selfObject.viewControllers.lastObject;
568594
if (!disappearingViewController) {
569595
callSuperBlock(viewController, animated);
570596
return;
571597
}
572598

573-
BOOL shouldCustomNavigationBarTransition = [selfObject shouldCustomTransitionAutomaticallyWithFirstViewController:disappearingViewController secondViewController:viewController];
574-
599+
BOOL shouldCustomNavigationBarTransition =
600+
[selfObject shouldCustomTransitionAutomaticallyForOperation:UINavigationControllerOperationPush firstViewController:disappearingViewController secondViewController:viewController];
575601
if (shouldCustomNavigationBarTransition) {
576602
[disappearingViewController addTransitionNavigationBarIfNeeded];
577603
disappearingViewController.prefersNavigationBarBackgroundViewHidden = YES;
@@ -655,20 +681,14 @@ + (void)load {
655681
}
656682

657683
- (void)handlePopViewControllerNavigationBarTransitionWithDisappearViewController:(UIViewController *)disappearViewController appearViewController:(UIViewController *)appearViewController {
658-
659-
if (self.delegate && ![self.delegate respondsToSelector:@selector(navigationController:animationControllerForOperation:fromViewController:toViewController:)]) {
660-
661-
BOOL shouldCustomNavigationBarTransition = [self shouldCustomTransitionAutomaticallyWithFirstViewController:disappearViewController secondViewController:appearViewController];
662-
663-
if (shouldCustomNavigationBarTransition) {
664-
[disappearViewController addTransitionNavigationBarIfNeeded];
665-
if (appearViewController.transitionNavigationBar) {
666-
// 假设从A→B→C,其中A设置了bar的样式,B跟随A所以B里没有设置bar样式的代码,C又把样式改为另一种,此时从C返回B时,由于B没有设置bar的样式的代码,所以bar的样式依然会保留C的,这就错了,所以每次都要手动改回来才保险
667-
[UIViewController replaceStyleForNavigationBar:appearViewController.transitionNavigationBar withNavigationBar:self.navigationBar];
668-
}
669-
disappearViewController.prefersNavigationBarBackgroundViewHidden = YES;
684+
BOOL shouldCustomNavigationBarTransition = [self shouldCustomTransitionAutomaticallyForOperation:UINavigationControllerOperationPop firstViewController:disappearViewController secondViewController:appearViewController];
685+
if (shouldCustomNavigationBarTransition) {
686+
[disappearViewController addTransitionNavigationBarIfNeeded];
687+
if (appearViewController.transitionNavigationBar) {
688+
// 假设从A→B→C,其中A设置了bar的样式,B跟随A所以B里没有设置bar样式的代码,C又把样式改为另一种,此时从C返回B时,由于B没有设置bar的样式的代码,所以bar的样式依然会保留C的,这就错了,所以每次都要手动改回来才保险
689+
[UIViewController replaceStyleForNavigationBar:appearViewController.transitionNavigationBar withNavigationBar:self.navigationBar];
670690
}
671-
691+
disappearViewController.prefersNavigationBarBackgroundViewHidden = YES;
672692
}
673693
}
674694

0 commit comments

Comments
 (0)