Skip to content

Commit 0ebb294

Browse files
committed
2.7.5
1 parent 13eed08 commit 0ebb294

19 files changed

Lines changed: 232 additions & 21 deletions

QMUIConfigurationTemplate/QMUIConfigurationTemplate.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ - (void)applyConfigurationTemplate {
7575

7676
QMUICMI.navBarHighlightedAlpha = 0.2f; // NavBarHighlightedAlpha : QMUINavigationButton 在 highlighted 时的 alpha
7777
QMUICMI.navBarDisabledAlpha = 0.2f; // NavBarDisabledAlpha : QMUINavigationButton 在 disabled 时的 alpha
78-
QMUICMI.navBarButtonFont = nil; // NavBarButtonFont : QMUINavigationButtonTypeNormal 的字体(由于系统存在一些 bug,这个属性默认不对 UIBarButtonItem 生效)
78+
QMUICMI.navBarButtonFont = nil; // NavBarButtonFont : QMUINavigationButtonTypeNormal 和 UINavigationBar 上的 UIBarButtonItem 的字体
7979
QMUICMI.navBarButtonFontBold = nil; // NavBarButtonFontBold : QMUINavigationButtonTypeBold 的字体
8080
QMUICMI.navBarBackgroundImage = nil; // NavBarBackgroundImage : UINavigationBar 的背景图
8181
QMUICMI.navBarShadowImage = nil; // NavBarShadowImage : UINavigationBar.shadowImage,也即导航栏底部那条分隔线

QMUIKit.podspec

Lines changed: 6 additions & 1 deletion
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 = "2.7.4"
3+
s.version = "2.7.5"
44
s.summary = "致力于提高项目 UI 开发效率的解决方案"
55
s.description = <<-DESC
66
QMUI iOS 是一个致力于提高项目 UI 开发效率的解决方案,其设计目的是用于辅助快速搭建一个具备基本设计还原效果的 iOS 项目,同时利用自身提供的丰富控件及兼容处理, 让开发者能专注于业务需求而无需耗费精力在基础代码的设计上。不管是新项目的创建,或是已有项目的维护,均可使开发效率和项目质量得到大幅度提升。
@@ -54,6 +54,11 @@ Pod::Spec.new do |s|
5454

5555
ss.dependency 'QMUIKit/QMUICore'
5656

57+
ss.subspec 'QMUICAAnimationExtension' do |sss|
58+
sss.source_files = 'QMUIKit/QMUIComponents/CAAnimation+QMUI.{h,m}'
59+
sss.dependency 'QMUIKit/QMUIComponents/QMUIMultipleDelegates'
60+
end
61+
5762
ss.subspec 'QMUINavigationTitleView' do |sss|
5863
sss.source_files = 'QMUIKit/QMUIComponents/QMUINavigationTitleView.{h,m}'
5964
sss.dependency 'QMUIKit/QMUIComponents/QMUIButton'

QMUIKit/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<key>CFBundlePackageType</key>
1616
<string>FMWK</string>
1717
<key>CFBundleShortVersionString</key>
18-
<string>2.7.4</string>
18+
<string>2.7.5</string>
1919
<key>CFBundleVersion</key>
2020
<string>$(CURRENT_PROJECT_VERSION)</string>
2121
<key>NSPrincipalClass</key>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//
2+
// CAAnimation+QMUI.h
3+
// QMUIKit
4+
//
5+
// Created by MoLice on 2018/7/31.
6+
// Copyright © 2018年 QMUI Team. All rights reserved.
7+
//
8+
9+
#import <QuartzCore/QuartzCore.h>
10+
11+
@interface CAAnimation (QMUI)
12+
13+
@property(nonatomic, copy) void (^qmui_animationDidStartBlock)(__kindof CAAnimation *aAnimation);
14+
@property(nonatomic, copy) void (^qmui_animationDidStopBlock)(__kindof CAAnimation *aAnimation, BOOL finished);
15+
@end
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
//
2+
// CAAnimation+QMUI.m
3+
// QMUIKit
4+
//
5+
// Created by MoLice on 2018/7/31.
6+
// Copyright © 2018年 QMUI Team. All rights reserved.
7+
//
8+
9+
#import "CAAnimation+QMUI.h"
10+
#import "QMUICore.h"
11+
#import "QMUIMultipleDelegates.h"
12+
13+
@interface _QMUICAAnimationDelegator : NSObject<CAAnimationDelegate>
14+
15+
@end
16+
17+
@implementation CAAnimation (QMUI)
18+
19+
+ (void)load {
20+
static dispatch_once_t onceToken;
21+
dispatch_once(&onceToken, ^{
22+
ExchangeImplementations(self.class, @selector(copyWithZone:), @selector(qmui_copyWithZone:));
23+
});
24+
}
25+
26+
- (id)qmui_copyWithZone:(NSZone *)zone {
27+
CAAnimation *animation = [self qmui_copyWithZone:zone];
28+
animation.qmui_multipleDelegatesEnabled = self.qmui_multipleDelegatesEnabled;
29+
animation.qmui_animationDidStartBlock = self.qmui_animationDidStartBlock;
30+
animation.qmui_animationDidStopBlock = self.qmui_animationDidStopBlock;
31+
return animation;
32+
}
33+
34+
- (void)enabledDelegateBlocks {
35+
self.qmui_multipleDelegatesEnabled = YES;
36+
BOOL shouldSetDelegator = !self.delegate;
37+
if (!shouldSetDelegator && [self.delegate isKindOfClass:[QMUIMultipleDelegates class]]) {
38+
QMUIMultipleDelegates *delegates = (QMUIMultipleDelegates *)self.delegate;
39+
NSPointerArray *array = delegates.delegates;
40+
for (NSUInteger i = 0; i < array.count; i++) {
41+
if ([((NSObject *)[array pointerAtIndex:i]) isKindOfClass:[_QMUICAAnimationDelegator class]]) {
42+
shouldSetDelegator = NO;
43+
break;
44+
}
45+
}
46+
}
47+
if (shouldSetDelegator) {
48+
self.delegate = [[_QMUICAAnimationDelegator alloc] init];// delegate is a strong property, it can retain _QMUICAAnimationDelegator
49+
}
50+
}
51+
52+
static char kAssociatedObjectKey_animationDidStartBlock;
53+
- (void)setQmui_animationDidStartBlock:(void (^)(__kindof CAAnimation *))qmui_animationDidStartBlock {
54+
objc_setAssociatedObject(self, &kAssociatedObjectKey_animationDidStartBlock, qmui_animationDidStartBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
55+
if (qmui_animationDidStartBlock) {
56+
[self enabledDelegateBlocks];
57+
}
58+
}
59+
60+
- (void (^)(__kindof CAAnimation *))qmui_animationDidStartBlock {
61+
return (void (^)(__kindof CAAnimation *))objc_getAssociatedObject(self, &kAssociatedObjectKey_animationDidStartBlock);
62+
}
63+
64+
static char kAssociatedObjectKey_animationDidStopBlock;
65+
- (void)setQmui_animationDidStopBlock:(void (^)(__kindof CAAnimation *, BOOL))qmui_animationDidStopBlock {
66+
objc_setAssociatedObject(self, &kAssociatedObjectKey_animationDidStopBlock, qmui_animationDidStopBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
67+
if (qmui_animationDidStopBlock) {
68+
[self enabledDelegateBlocks];
69+
}
70+
}
71+
72+
- (void (^)(__kindof CAAnimation *, BOOL))qmui_animationDidStopBlock {
73+
return (void (^)(__kindof CAAnimation *, BOOL))objc_getAssociatedObject(self, &kAssociatedObjectKey_animationDidStopBlock);
74+
}
75+
76+
@end
77+
78+
@implementation _QMUICAAnimationDelegator
79+
80+
- (void)animationDidStart:(CAAnimation *)anim {
81+
if (anim.qmui_animationDidStartBlock) {
82+
anim.qmui_animationDidStartBlock(anim);
83+
}
84+
}
85+
86+
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
87+
if (anim.qmui_animationDidStopBlock) {
88+
anim.qmui_animationDidStopBlock(anim, flag);
89+
}
90+
}
91+
92+
@end

QMUIKit/QMUIComponents/QMUIModalPresentationViewController.m

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,18 @@ + (BOOL)hideAllVisibleModalPresentationViewControllerIfCan {
666666

667667
@implementation QMUIModalPresentationWindow
668668

669+
- (void)layoutSubviews {
670+
[super layoutSubviews];
671+
if (self.rootViewController) {
672+
673+
// https://github.com/QMUI/QMUI_iOS/issues/375
674+
UIView *rootView = self.rootViewController.view;
675+
if (CGRectGetMinY(rootView.frame) > 0 && ![UIApplication sharedApplication].statusBarHidden && StatusBarHeight > CGRectGetMinY(rootView.frame)) {
676+
rootView.frame = self.bounds;
677+
}
678+
}
679+
}
680+
669681
@end
670682

671683
@implementation UIViewController (QMUIModalPresentationViewController)

QMUIKit/QMUIComponents/QMUIMultipleDelegates/NSObject+QMUIMultipleDelegates.m

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,17 @@ - (void)qmui_registerDelegateSelector:(SEL)getter {
6464
// 为这个 selector 创建一个 QMUIMultipleDelegates 容器
6565
NSString *delegateGetterKey = NSStringFromSelector(getter);
6666
if (!self.qmuimd_delegates[delegateGetterKey]) {
67-
self.qmuimd_delegates[delegateGetterKey] = [[QMUIMultipleDelegates alloc] init];
67+
objc_property_t prop = class_getProperty(self.class, delegateGetterKey.UTF8String);
68+
const char *propAttributes = property_getAttributes(prop);
69+
NSString *attributes = [NSString stringWithUTF8String:propAttributes];
70+
if ([attributes containsString:@"&"]) {
71+
// & means strong property
72+
// @see https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html#//apple_ref/doc/uid/TP40008048-CH101-SW5
73+
self.qmuimd_delegates[delegateGetterKey] = [QMUIMultipleDelegates strongDelegates];
74+
} else {
75+
// weak property
76+
self.qmuimd_delegates[delegateGetterKey] = [QMUIMultipleDelegates weakDelegates];
77+
}
6878
}
6979

7080
// 避免为某个 class 重复替换同一个方法的实现
@@ -115,6 +125,15 @@ - (void)qmui_registerDelegateSelector:(SEL)getter {
115125
Method newMethod = class_getInstanceMethod(targetClass, newDelegateSetter);
116126
method_exchangeImplementations(originMethod, newMethod);
117127
}
128+
129+
// 如果原来已经有 delegate,则将其加到新建的容器里
130+
// @see https://github.com/QMUI/QMUI_iOS/issues/378
131+
BeginIgnorePerformSelectorLeaksWarning
132+
id originDelegate = [self performSelector:getter];
133+
if (originDelegate && originDelegate != self.qmuimd_delegates[delegateGetterKey]) {
134+
[self performSelector:originDelegateSetter withObject:originDelegate];
135+
}
136+
EndIgnorePerformSelectorLeaksWarning
118137
}
119138

120139
- (void)qmui_removeDelegate:(id)delegate {

QMUIKit/QMUIComponents/QMUIMultipleDelegates/QMUIMultipleDelegates.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
/// 存放多个 delegate 指针的容器,必须搭配其他控件使用,一般不需要你自己 init。作用是让某个 class 支持同时存在多个 delegate。更多说明请查看 NSObject (QMUIMultipleDelegates) 的注释。
1414
@interface QMUIMultipleDelegates : NSObject
1515

16+
+ (instancetype)weakDelegates;
17+
+ (instancetype)strongDelegates;
18+
1619
@property(nonatomic, strong, readonly) NSPointerArray *delegates;
1720

1821
- (void)addDelegate:(id)delegate;

QMUIKit/QMUIComponents/QMUIMultipleDelegates/QMUIMultipleDelegates.m

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,23 @@
1010
#import "NSPointerArray+QMUI.h"
1111
#import <objc/runtime.h>
1212

13+
@interface QMUIMultipleDelegates ()
14+
15+
@property(nonatomic, strong, readwrite) NSPointerArray *delegates;
16+
@end
17+
1318
@implementation QMUIMultipleDelegates
1419

15-
- (instancetype)init {
16-
self = [super init];
17-
if (self) {
18-
_delegates = [NSPointerArray weakObjectsPointerArray];
19-
}
20-
return self;
20+
+ (instancetype)weakDelegates {
21+
QMUIMultipleDelegates *delegates = [[QMUIMultipleDelegates alloc] init];
22+
delegates.delegates = [NSPointerArray weakObjectsPointerArray];
23+
return delegates;
24+
}
25+
26+
+ (instancetype)strongDelegates {
27+
QMUIMultipleDelegates *delegates = [[QMUIMultipleDelegates alloc] init];
28+
delegates.delegates = [NSPointerArray strongObjectsPointerArray];
29+
return delegates;
2130
}
2231

2332
- (void)addDelegate:(id)delegate {

QMUIKit/QMUIComponents/QMUITestView.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
@interface QMUITestView : UIView
1212

13+
@property(nonatomic, strong) id delegate;
1314
@end
1415

1516

0 commit comments

Comments
 (0)