Skip to content

Commit

Permalink
4.5.1
Browse files Browse the repository at this point in the history
  • Loading branch information
molicechen committed Aug 23, 2022
1 parent 7cee929 commit aec060b
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 23 deletions.
2 changes: 1 addition & 1 deletion QMUIKit.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "QMUIKit"
s.version = "4.5.0"
s.version = "4.5.1"
s.summary = "致力于提高项目 UI 开发效率的解决方案"
s.description = <<-DESC
QMUI iOS 是一个致力于提高项目 UI 开发效率的解决方案,其设计目的是用于辅助快速搭建一个具备基本设计还原效果的 iOS 项目,同时利用自身提供的丰富控件及兼容处理, 让开发者能专注于业务需求而无需耗费精力在基础代码的设计上。不管是新项目的创建,或是已有项目的维护,均可使开发效率和项目质量得到大幅度提升。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,16 @@ + (void)load {
}
});

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

// call super
void (*originSelectorIMP)(id, SEL, UIImage *, UIBarPosition, UIBarMetrics);
originSelectorIMP = (void (*)(id, SEL, UIImage *, UIBarPosition, UIBarMetrics))originalIMPProvider();
originSelectorIMP(selfObject, originCMD, image, barPosition, barMetrics);
void (*originSelectorIMP)(id, SEL, UIImage *, UIBarMetrics);
originSelectorIMP = (void (*)(id, SEL, UIImage *, UIBarMetrics))originalIMPProvider();
originSelectorIMP(selfObject, originCMD, image, barMetrics);

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

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

Expand Down
28 changes: 21 additions & 7 deletions QMUIKit/QMUIComponents/QMUIAlertController.m
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,7 @@ - (void)viewDidLayoutSubviews {
BOOL hasMessage = (self.messageLabel.text.length > 0 && !self.messageLabel.hidden);
BOOL hasTextField = self.alertTextFields.count > 0;
BOOL hasCustomView = !!_customView;
BOOL shouldShowSeparatorAtTopOfButtonAtFirstLine = hasTitle || hasMessage || hasCustomView;
CGFloat contentOriginY = 0;

self.maskView.frame = self.view.bounds;
Expand Down Expand Up @@ -606,16 +607,21 @@ - (void)viewDidLayoutSubviews {
// 对齐系统,先 add 的在右边,后 add 的在左边
QMUIAlertAction *leftAction = newOrderActions[1];
leftAction.button.frame = CGRectMake(0, contentOriginY, CGRectGetWidth(self.buttonScrollView.bounds) / 2, self.alertButtonHeight);
leftAction.button.qmui_borderPosition = QMUIViewBorderPositionTop|QMUIViewBorderPositionRight;
leftAction.button.qmui_borderPosition = QMUIViewBorderPositionRight;
QMUIAlertAction *rightAction = newOrderActions[0];
rightAction.button.frame = CGRectMake(CGRectGetMaxX(leftAction.button.frame), contentOriginY, CGRectGetWidth(self.buttonScrollView.bounds) / 2, self.alertButtonHeight);
rightAction.button.qmui_borderPosition = QMUIViewBorderPositionTop;
if (shouldShowSeparatorAtTopOfButtonAtFirstLine) {
leftAction.button.qmui_borderPosition |= QMUIViewBorderPositionTop;
rightAction.button.qmui_borderPosition = QMUIViewBorderPositionTop;
}
contentOriginY = CGRectGetMaxY(leftAction.button.frame);
} else {
for (int i = 0; i < newOrderActions.count; i++) {
QMUIAlertAction *action = newOrderActions[i];
action.button.frame = CGRectMake(0, contentOriginY, CGRectGetWidth(self.containerView.bounds), self.alertButtonHeight);
action.button.qmui_borderPosition = QMUIViewBorderPositionTop;
if (i > 0 || shouldShowSeparatorAtTopOfButtonAtFirstLine) {
action.button.qmui_borderPosition = QMUIViewBorderPositionTop;
}
contentOriginY = CGRectGetMaxY(action.button.frame);
}
}
Expand Down Expand Up @@ -717,17 +723,25 @@ - (void)viewDidLayoutSubviews {
if (action.style == QMUIAlertActionStyleCancel && i == newOrderActions.count - 1) {
continue;
} else {
BOOL isFirstLine = floor(i / columnCount) == 0;
BOOL isLastColumn = fmod(i + 1, columnCount) == 0;
BOOL shouldShowSeparatorAtTop = !isFirstLine || shouldShowSeparatorAtTopOfButtonAtFirstLine;
BOOL shouldShowSeparatorAtRight = !isLastColumn;// 单列时全都不用显示右分隔线,多列时最后一列不用显示右分隔线
action.button.frame = CGRectMake(alertActionsLayoutX, alertActionsLayoutY, alertActionsWidth, self.sheetButtonHeight);
if (fmodf(i + 1, columnCount) == 0) {
action.button.qmui_borderPosition = QMUIViewBorderPositionTop;
if (isLastColumn) {
alertActionsLayoutX = 0;
alertActionsLayoutY = CGRectGetMaxY(action.button.frame);
} else {
action.button.qmui_borderPosition = QMUIViewBorderPositionTop|QMUIViewBorderPositionRight;
alertActionsLayoutX += alertActionsWidth;
}

contentOriginY = MAX(contentOriginY, CGRectGetMaxY(action.button.frame));

if (shouldShowSeparatorAtTop) {
action.button.qmui_borderPosition |= QMUIViewBorderPositionTop;
}
if (shouldShowSeparatorAtRight) {
action.button.qmui_borderPosition |= QMUIViewBorderPositionRight;
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion QMUIKit/QMUIKit.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#ifndef QMUIKit_h
#define QMUIKit_h

static NSString * const QMUI_VERSION = @"4.5.0";
static NSString * const QMUI_VERSION = @"4.5.1";

#if __has_include("CAAnimation+QMUI.h")
#import "CAAnimation+QMUI.h"
Expand Down
2 changes: 1 addition & 1 deletion QMUIKit/UIKitExtensions/NSObject+QMUI.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ NS_ASSUME_NONNULL_BEGIN
/// 获取当前对象的所有 @property、方法,不包含父类的
@property(nonatomic, copy, readonly) NSString *qmui_shortMethodList;

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

/// 获取当前 UIView 层级树信息(只对 UIView 有效)
Expand Down
30 changes: 28 additions & 2 deletions QMUIKit/UIKitExtensions/NSObject+QMUI.m
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,9 @@ - (void)qmui_enumrateIvarsUsingBlock:(void (^)(Ivar ivar, NSString *ivarDescript

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

- (NSString *)qmui_ivarList {
return [self performSelector:NSSelectorFromString(@"_ivarDescription")];
NSString *systemResult = [self performSelector:NSSelectorFromString(@"_ivarDescription")];
NSRegularExpression *regx = [NSRegularExpression regularExpressionWithPattern:@"^(\\s+)(\\S+)" options:NSRegularExpressionCaseInsensitive error:nil];
NSMutableArray<NSString *> *lines = [systemResult componentsSeparatedByString:@"\n"].mutableCopy;
[lines enumerateObjectsUsingBlock:^(NSString *line, NSUInteger idx, BOOL * _Nonnull stop) {

// 过滤掉空行或者 struct 结尾的"}"
if (line.qmui_trim.length <= 2) return;

// 有些 struct 类型的变量,会把 struct 的成员也缩进打出来,所以用这种方式过滤掉
if ([line hasPrefix:@"\t\t"]) return;

NSTextCheckingResult *regxResult = [regx firstMatchInString:line options:NSMatchingReportCompletion range:NSMakeRange(0, line.length)];
if (regxResult.numberOfRanges < 3) return;

NSRange indentRange = [regxResult rangeAtIndex:1];
NSRange offsetRange = NSMakeRange(NSMaxRange(indentRange), 0);
NSRange ivarNameRange = [regxResult rangeAtIndex:2];
NSString *ivarName = [line substringWithRange:ivarNameRange];
Ivar ivar = class_getInstanceVariable(self.class, ivarName.UTF8String);
ptrdiff_t ivarOffset = ivar_getOffset(ivar);
NSString *lineWithOffset = [line stringByReplacingCharactersInRange:offsetRange withString:[NSString stringWithFormat:@"[%@|0x%@]", @(ivarOffset), [NSString stringWithFormat:@"%lx", (NSInteger)ivarOffset].uppercaseString]];
[lines setObject:lineWithOffset atIndexedSubscript:idx];
}];
NSString *result = [lines componentsJoinedByString:@"\n"];
return result;
}

- (NSString *)qmui_viewInfo {
Expand Down
2 changes: 1 addition & 1 deletion QMUIKit/UIKitExtensions/UIScrollView+QMUI.m
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ + (void)load {
}

- (BOOL)qmui_alreadyAtTop {
if (((NSInteger)self.contentOffset.y) == -((NSInteger)self.adjustedContentInset.top)) {
if (CGFloatEqualToFloat(self.contentOffset.y, -self.adjustedContentInset.top)) {
return YES;
}

Expand Down
5 changes: 4 additions & 1 deletion QMUIKit/UIKitExtensions/UIView+QMUI.m
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,10 @@ - (void)setQmui_outsideEdge:(UIEdgeInsets)qmui_outsideEdge {
OverrideImplementation([UIView class], @selector(pointInside:withEvent:), ^id(__unsafe_unretained Class originClass, SEL originCMD, IMP (^originalIMPProvider)(void)) {
return ^BOOL(UIControl *selfObject, CGPoint point, UIEvent *event) {

if (!UIEdgeInsetsEqualToEdgeInsets(selfObject.qmui_outsideEdge, UIEdgeInsetsZero)) {
if (!UIEdgeInsetsEqualToEdgeInsets(selfObject.qmui_outsideEdge, UIEdgeInsetsZero)
&& selfObject.alpha > 0.01
&& !selfObject.hidden
&& !CGRectIsEmpty(selfObject.frame)) {
CGRect rect = UIEdgeInsetsInsetRect(selfObject.bounds, selfObject.qmui_outsideEdge);
BOOL result = CGRectContainsPoint(rect, point);
return result;
Expand Down
4 changes: 2 additions & 2 deletions qmui.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1960,7 +1960,7 @@
"@loader_path/Frameworks",
);
MACH_O_TYPE = mh_dylib;
MARKETING_VERSION = 4.5.0;
MARKETING_VERSION = 4.5.1;
MTL_ENABLE_DEBUG_INFO = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.qmui.QMUIKit;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -2004,7 +2004,7 @@
"@loader_path/Frameworks",
);
MACH_O_TYPE = mh_dylib;
MARKETING_VERSION = 4.5.0;
MARKETING_VERSION = 4.5.1;
MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = com.qmui.QMUIKit;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down

0 comments on commit aec060b

Please sign in to comment.