Skip to content

Commit aec060b

Browse files
author
molicechen
committed
4.5.1
1 parent 7cee929 commit aec060b

File tree

9 files changed

+67
-23
lines changed

9 files changed

+67
-23
lines changed

QMUIKit.podspec

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

QMUIKit/QMUIComponents/NavigationBarTransition/UINavigationBar+Transition.m

+8-7
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,16 @@ + (void)load {
5454
}
5555
});
5656

57-
OverrideImplementation([UINavigationBar class], @selector(setBackgroundImage:forBarPosition:barMetrics:), ^id(__unsafe_unretained Class originClass, SEL originCMD, IMP (^originalIMPProvider)(void)) {
58-
return ^(UINavigationBar *selfObject, UIImage *image, UIBarPosition barPosition, UIBarMetrics barMetrics) {
57+
OverrideImplementation([UINavigationBar class], @selector(setBackgroundImage:forBarMetrics:), ^id(__unsafe_unretained Class originClass, SEL originCMD, IMP (^originalIMPProvider)(void)) {
58+
return ^(UINavigationBar *selfObject, UIImage *image, UIBarMetrics barMetrics) {
5959

6060
// call super
61-
void (*originSelectorIMP)(id, SEL, UIImage *, UIBarPosition, UIBarMetrics);
62-
originSelectorIMP = (void (*)(id, SEL, UIImage *, UIBarPosition, UIBarMetrics))originalIMPProvider();
63-
originSelectorIMP(selfObject, originCMD, image, barPosition, barMetrics);
61+
void (*originSelectorIMP)(id, SEL, UIImage *, UIBarMetrics);
62+
originSelectorIMP = (void (*)(id, SEL, UIImage *, UIBarMetrics))originalIMPProvider();
63+
originSelectorIMP(selfObject, originCMD, image, barMetrics);
6464

6565
if (selfObject.qmuinb_copyStylesToBar) {
66-
[selfObject.qmuinb_copyStylesToBar setBackgroundImage:image forBarPosition:barPosition barMetrics:barMetrics];
66+
[selfObject.qmuinb_copyStylesToBar setBackgroundImage:image forBarMetrics:barMetrics];
6767
}
6868
};
6969
});
@@ -165,6 +165,7 @@ + (void)load {
165165
// iOS 14 开启 customNavigationBarTransitionKey 的情况下转场效果错误
166166
// https://github.com/Tencent/QMUI_iOS/issues/1081
167167
if (@available(iOS 14.0, *)) {
168+
// - [UINavigationBar _accessibility_navigationController]
168169
OverrideImplementation([_QMUITransitionNavigationBar class], NSSelectorFromString([NSString stringWithFormat:@"_%@_%@", @"accessibility", @"navigationController"]), ^id(__unsafe_unretained Class originClass, SEL originCMD, IMP (^originalIMPProvider)(void)) {
169170
return ^UINavigationController *(_QMUITransitionNavigationBar *selfObject) {
170171
if (selfObject.originalNavigationBar) {
@@ -184,7 +185,7 @@ + (void)load {
184185

185186
#ifdef IOS15_SDK_ALLOWED
186187
if (@available(iOS 15.0, *)) {
187-
// -[UINavigationBar _didMoveFromWindow:toWindow:]
188+
// - [UINavigationBar _didMoveFromWindow:toWindow:]
188189
OverrideImplementation([_QMUITransitionNavigationBar class], NSSelectorFromString(@"_didMoveFromWindow:toWindow:"), ^id(__unsafe_unretained Class originClass, SEL originCMD, IMP (^originalIMPProvider)(void)) {
189190
return ^(_QMUITransitionNavigationBar *selfObject, UIWindow *firstArgv, UIWindow *secondArgv) {
190191

QMUIKit/QMUIComponents/QMUIAlertController.m

+21-7
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,7 @@ - (void)viewDidLayoutSubviews {
536536
BOOL hasMessage = (self.messageLabel.text.length > 0 && !self.messageLabel.hidden);
537537
BOOL hasTextField = self.alertTextFields.count > 0;
538538
BOOL hasCustomView = !!_customView;
539+
BOOL shouldShowSeparatorAtTopOfButtonAtFirstLine = hasTitle || hasMessage || hasCustomView;
539540
CGFloat contentOriginY = 0;
540541

541542
self.maskView.frame = self.view.bounds;
@@ -606,16 +607,21 @@ - (void)viewDidLayoutSubviews {
606607
// 对齐系统,先 add 的在右边,后 add 的在左边
607608
QMUIAlertAction *leftAction = newOrderActions[1];
608609
leftAction.button.frame = CGRectMake(0, contentOriginY, CGRectGetWidth(self.buttonScrollView.bounds) / 2, self.alertButtonHeight);
609-
leftAction.button.qmui_borderPosition = QMUIViewBorderPositionTop|QMUIViewBorderPositionRight;
610+
leftAction.button.qmui_borderPosition = QMUIViewBorderPositionRight;
610611
QMUIAlertAction *rightAction = newOrderActions[0];
611612
rightAction.button.frame = CGRectMake(CGRectGetMaxX(leftAction.button.frame), contentOriginY, CGRectGetWidth(self.buttonScrollView.bounds) / 2, self.alertButtonHeight);
612-
rightAction.button.qmui_borderPosition = QMUIViewBorderPositionTop;
613+
if (shouldShowSeparatorAtTopOfButtonAtFirstLine) {
614+
leftAction.button.qmui_borderPosition |= QMUIViewBorderPositionTop;
615+
rightAction.button.qmui_borderPosition = QMUIViewBorderPositionTop;
616+
}
613617
contentOriginY = CGRectGetMaxY(leftAction.button.frame);
614618
} else {
615619
for (int i = 0; i < newOrderActions.count; i++) {
616620
QMUIAlertAction *action = newOrderActions[i];
617621
action.button.frame = CGRectMake(0, contentOriginY, CGRectGetWidth(self.containerView.bounds), self.alertButtonHeight);
618-
action.button.qmui_borderPosition = QMUIViewBorderPositionTop;
622+
if (i > 0 || shouldShowSeparatorAtTopOfButtonAtFirstLine) {
623+
action.button.qmui_borderPosition = QMUIViewBorderPositionTop;
624+
}
619625
contentOriginY = CGRectGetMaxY(action.button.frame);
620626
}
621627
}
@@ -717,17 +723,25 @@ - (void)viewDidLayoutSubviews {
717723
if (action.style == QMUIAlertActionStyleCancel && i == newOrderActions.count - 1) {
718724
continue;
719725
} else {
726+
BOOL isFirstLine = floor(i / columnCount) == 0;
727+
BOOL isLastColumn = fmod(i + 1, columnCount) == 0;
728+
BOOL shouldShowSeparatorAtTop = !isFirstLine || shouldShowSeparatorAtTopOfButtonAtFirstLine;
729+
BOOL shouldShowSeparatorAtRight = !isLastColumn;// 单列时全都不用显示右分隔线,多列时最后一列不用显示右分隔线
720730
action.button.frame = CGRectMake(alertActionsLayoutX, alertActionsLayoutY, alertActionsWidth, self.sheetButtonHeight);
721-
if (fmodf(i + 1, columnCount) == 0) {
722-
action.button.qmui_borderPosition = QMUIViewBorderPositionTop;
731+
if (isLastColumn) {
723732
alertActionsLayoutX = 0;
724733
alertActionsLayoutY = CGRectGetMaxY(action.button.frame);
725734
} else {
726-
action.button.qmui_borderPosition = QMUIViewBorderPositionTop|QMUIViewBorderPositionRight;
727735
alertActionsLayoutX += alertActionsWidth;
728736
}
729-
730737
contentOriginY = MAX(contentOriginY, CGRectGetMaxY(action.button.frame));
738+
739+
if (shouldShowSeparatorAtTop) {
740+
action.button.qmui_borderPosition |= QMUIViewBorderPositionTop;
741+
}
742+
if (shouldShowSeparatorAtRight) {
743+
action.button.qmui_borderPosition |= QMUIViewBorderPositionRight;
744+
}
731745
}
732746
}
733747
}

QMUIKit/QMUIKit.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#ifndef QMUIKit_h
1414
#define QMUIKit_h
1515

16-
static NSString * const QMUI_VERSION = @"4.5.0";
16+
static NSString * const QMUI_VERSION = @"4.5.1";
1717

1818
#if __has_include("CAAnimation+QMUI.h")
1919
#import "CAAnimation+QMUI.h"

QMUIKit/UIKitExtensions/NSObject+QMUI.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ NS_ASSUME_NONNULL_BEGIN
301301
/// 获取当前对象的所有 @property、方法,不包含父类的
302302
@property(nonatomic, copy, readonly) NSString *qmui_shortMethodList;
303303

304-
/// 获取当前对象的所有 Ivar 变量
304+
/// 获取当前对象的所有 Ivar 变量,并在 Ivar 名字前面显示该 Ivar 的 offset,会同时显示十进制和十六进制,以“|”隔开。
305305
@property(nonatomic, copy, readonly) NSString *qmui_ivarList;
306306

307307
/// 获取当前 UIView 层级树信息(只对 UIView 有效)

QMUIKit/UIKitExtensions/NSObject+QMUI.m

+28-2
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,9 @@ - (void)qmui_enumrateIvarsUsingBlock:(void (^)(Ivar ivar, NSString *ivarDescript
130130

131131
- (void)qmui_enumrateIvarsIncludingInherited:(BOOL)includingInherited usingBlock:(void (^)(Ivar ivar, NSString *ivarDescription))block {
132132
NSMutableArray<NSString *> *ivarDescriptions = [NSMutableArray new];
133-
NSString *ivarList = [self qmui_ivarList];
133+
BeginIgnorePerformSelectorLeaksWarning
134+
NSString *ivarList = [self performSelector:NSSelectorFromString(@"_ivarDescription")];
135+
EndIgnorePerformSelectorLeaksWarning
134136
NSError *error;
135137
NSRegularExpression *reg = [NSRegularExpression regularExpressionWithPattern:[NSString stringWithFormat:@"in %@:(.*?)((?=in \\w+:)|$)", NSStringFromClass(self.class)] options:NSRegularExpressionDotMatchesLineSeparators error:&error];
136138
if (!error) {
@@ -456,7 +458,31 @@ - (NSString *)qmui_shortMethodList {
456458
}
457459

458460
- (NSString *)qmui_ivarList {
459-
return [self performSelector:NSSelectorFromString(@"_ivarDescription")];
461+
NSString *systemResult = [self performSelector:NSSelectorFromString(@"_ivarDescription")];
462+
NSRegularExpression *regx = [NSRegularExpression regularExpressionWithPattern:@"^(\\s+)(\\S+)" options:NSRegularExpressionCaseInsensitive error:nil];
463+
NSMutableArray<NSString *> *lines = [systemResult componentsSeparatedByString:@"\n"].mutableCopy;
464+
[lines enumerateObjectsUsingBlock:^(NSString *line, NSUInteger idx, BOOL * _Nonnull stop) {
465+
466+
// 过滤掉空行或者 struct 结尾的"}"
467+
if (line.qmui_trim.length <= 2) return;
468+
469+
// 有些 struct 类型的变量,会把 struct 的成员也缩进打出来,所以用这种方式过滤掉
470+
if ([line hasPrefix:@"\t\t"]) return;
471+
472+
NSTextCheckingResult *regxResult = [regx firstMatchInString:line options:NSMatchingReportCompletion range:NSMakeRange(0, line.length)];
473+
if (regxResult.numberOfRanges < 3) return;
474+
475+
NSRange indentRange = [regxResult rangeAtIndex:1];
476+
NSRange offsetRange = NSMakeRange(NSMaxRange(indentRange), 0);
477+
NSRange ivarNameRange = [regxResult rangeAtIndex:2];
478+
NSString *ivarName = [line substringWithRange:ivarNameRange];
479+
Ivar ivar = class_getInstanceVariable(self.class, ivarName.UTF8String);
480+
ptrdiff_t ivarOffset = ivar_getOffset(ivar);
481+
NSString *lineWithOffset = [line stringByReplacingCharactersInRange:offsetRange withString:[NSString stringWithFormat:@"[%@|0x%@]", @(ivarOffset), [NSString stringWithFormat:@"%lx", (NSInteger)ivarOffset].uppercaseString]];
482+
[lines setObject:lineWithOffset atIndexedSubscript:idx];
483+
}];
484+
NSString *result = [lines componentsJoinedByString:@"\n"];
485+
return result;
460486
}
461487

462488
- (NSString *)qmui_viewInfo {

QMUIKit/UIKitExtensions/UIScrollView+QMUI.m

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ + (void)load {
7474
}
7575

7676
- (BOOL)qmui_alreadyAtTop {
77-
if (((NSInteger)self.contentOffset.y) == -((NSInteger)self.adjustedContentInset.top)) {
77+
if (CGFloatEqualToFloat(self.contentOffset.y, -self.adjustedContentInset.top)) {
7878
return YES;
7979
}
8080

QMUIKit/UIKitExtensions/UIView+QMUI.m

+4-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,10 @@ - (void)setQmui_outsideEdge:(UIEdgeInsets)qmui_outsideEdge {
8888
OverrideImplementation([UIView class], @selector(pointInside:withEvent:), ^id(__unsafe_unretained Class originClass, SEL originCMD, IMP (^originalIMPProvider)(void)) {
8989
return ^BOOL(UIControl *selfObject, CGPoint point, UIEvent *event) {
9090

91-
if (!UIEdgeInsetsEqualToEdgeInsets(selfObject.qmui_outsideEdge, UIEdgeInsetsZero)) {
91+
if (!UIEdgeInsetsEqualToEdgeInsets(selfObject.qmui_outsideEdge, UIEdgeInsetsZero)
92+
&& selfObject.alpha > 0.01
93+
&& !selfObject.hidden
94+
&& !CGRectIsEmpty(selfObject.frame)) {
9295
CGRect rect = UIEdgeInsetsInsetRect(selfObject.bounds, selfObject.qmui_outsideEdge);
9396
BOOL result = CGRectContainsPoint(rect, point);
9497
return result;

qmui.xcodeproj/project.pbxproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -1960,7 +1960,7 @@
19601960
"@loader_path/Frameworks",
19611961
);
19621962
MACH_O_TYPE = mh_dylib;
1963-
MARKETING_VERSION = 4.5.0;
1963+
MARKETING_VERSION = 4.5.1;
19641964
MTL_ENABLE_DEBUG_INFO = YES;
19651965
PRODUCT_BUNDLE_IDENTIFIER = com.qmui.QMUIKit;
19661966
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -2004,7 +2004,7 @@
20042004
"@loader_path/Frameworks",
20052005
);
20062006
MACH_O_TYPE = mh_dylib;
2007-
MARKETING_VERSION = 4.5.0;
2007+
MARKETING_VERSION = 4.5.1;
20082008
MTL_ENABLE_DEBUG_INFO = NO;
20092009
PRODUCT_BUNDLE_IDENTIFIER = com.qmui.QMUIKit;
20102010
PRODUCT_NAME = "$(TARGET_NAME)";

0 commit comments

Comments
 (0)