Skip to content

Commit

Permalink
4.4.3
Browse files Browse the repository at this point in the history
  • Loading branch information
molicechen committed Dec 31, 2021
1 parent 137e54f commit 919fee5
Show file tree
Hide file tree
Showing 11 changed files with 135 additions and 49 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.4.2"
s.version = "4.4.3"
s.summary = "致力于提高项目 UI 开发效率的解决方案"
s.description = <<-DESC
QMUI iOS 是一个致力于提高项目 UI 开发效率的解决方案,其设计目的是用于辅助快速搭建一个具备基本设计还原效果的 iOS 项目,同时利用自身提供的丰富控件及兼容处理, 让开发者能专注于业务需求而无需耗费精力在基础代码的设计上。不管是新项目的创建,或是已有项目的维护,均可使开发效率和项目质量得到大幅度提升。
Expand Down
5 changes: 5 additions & 0 deletions QMUIKit/QMUIComponents/QMUITheme/UIImage+QMUITheme.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ NS_ASSUME_NONNULL_BEGIN
*/
+ (UIImage *)qmui_imageWithThemeManagerName:(__kindof NSObject<NSCopying> *)name provider:(UIImage *(^)(__kindof QMUIThemeManager *manager, __kindof NSObject<NSCopying> * _Nullable identifier, __kindof NSObject * _Nullable theme))provider;

/**
内部用,标志 QMUIThemeImage 对 UIImage (QMUI) 里使用动态颜色生成动态图片的适配 hook 是否已生效。例如在配置表这种“加载时机特别早”的场景,此时 UIImage (QMUITheme) +load 方法尚未被调用,这些 hook 还没生效,此时如果你使用 [UIImage qmui_imageWithTintColor:dynamicColor] 得到的 image 是无法自动响应 theme 切换的。
*/
@property(class, nonatomic, assign) BOOL qmui_generatorSupportsDynamicColor;

@end

NS_ASSUME_NONNULL_END
7 changes: 7 additions & 0 deletions QMUIKit/QMUIComponents/QMUITheme/UIImage+QMUITheme.m
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,11 @@ @implementation UIImage (QMUITheme)

QMUISynthesizeBOOLProperty(qmui_shouldUseSystemIMP, setQmui_shouldUseSystemIMP)

static BOOL generatorSupportsDynamicColor = NO;
+ (BOOL)qmui_generatorSupportsDynamicColor {
return generatorSupportsDynamicColor;
}

+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Expand Down Expand Up @@ -486,6 +491,8 @@ + (void)load {
};
});
}

generatorSupportsDynamicColor = YES;
});
}

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.4.2";
static NSString * const QMUI_VERSION = @"4.4.3";

#if __has_include("CAAnimation+QMUI.h")
#import "CAAnimation+QMUI.h"
Expand Down
7 changes: 6 additions & 1 deletion QMUIKit/UIKitExtensions/NSString+QMUI.m
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,13 @@ - (NSString *)qmui_stringByEncodingUserInputQuery {
}

- (NSString *)qmui_capitalizedString {
if (self.length)
if (self.length) {
NSRange range = [self rangeOfComposedCharacterSequenceAtIndex:0];
if (range.length > 1) {
return self;// 说明这个字符没法大写
}
return [NSString stringWithFormat:@"%@%@", [self substringToIndex:1].uppercaseString, [self substringFromIndex:1]].copy;
}
return nil;
}

Expand Down
18 changes: 6 additions & 12 deletions QMUIKit/UIKitExtensions/QMUIStringPrivate.m
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,7 @@ + (void)qmuisafety_NSString {
BOOL isValidatedIndex = index <= selfObject.length;
if (!isValidatedIndex) {
NSString *logString = [NSString stringWithFormat:@"%@ 传入了一个超过字符串长度的 index: %@,原字符串为: %@(%@)", NSStringFromSelector(originCMD), @(index), selfObject, @(selfObject.length)];
NSAssert(NO, logString);
QMUILogWarn(@"QMUIStringSafety", @"%@", logString);
QMUIAssert(NO, @"QMUIStringSafety", @"%@", logString);
return @"";// 系统 substringFromIndex: 返回值的标志是 nonnull
}
}
Expand All @@ -176,8 +175,7 @@ + (void)qmuisafety_NSString {
BOOL isValidatedIndex = range.location == index || NSMaxRange(range) == index;
if (!isValidatedIndex) {
NSString *logString = [NSString stringWithFormat:@"试图在 ComposedCharacterSequence 中间用 %@ 裁剪字符串,可能导致乱码、crash。原字符串为“%@”(%@),index 为 %@,命中的 ComposedCharacterSequence range 为 %@", NSStringFromSelector(originCMD), selfObject, @(selfObject.length), @(index), NSStringFromRange(range)];
NSAssert(NO, logString);
QMUILogWarn(@"QMUIStringSafety", @"%@", logString);
QMUIAssert(NO, @"QMUIStringSafety", @"%@", logString);
index = range.location;
}
}
Expand All @@ -200,8 +198,7 @@ + (void)qmuisafety_NSString {
BOOL isValidatedIndex = index <= selfObject.length;
if (!isValidatedIndex) {
NSString *logString = [NSString stringWithFormat:@"%@ 传入了一个超过字符串长度的 index: %@,原字符串为: %@(%@)", NSStringFromSelector(originCMD), @(index), selfObject, @(selfObject.length)];
NSAssert(NO, logString);
QMUILogWarn(@"QMUIStringSafety", @"%@", logString);
QMUIAssert(NO, @"QMUIStringSafety", @"%@", logString);
return @"";// 系统 substringToIndex: 返回值的标志是 nonnull,但返回 nil 比返回 @"" 更安全
}
}
Expand All @@ -213,8 +210,7 @@ + (void)qmuisafety_NSString {
BOOL isValidatedIndex = range.location == index;
if (!isValidatedIndex) {
NSString *logString = [NSString stringWithFormat:@"试图在 ComposedCharacterSequence 中间用 %@ 裁剪字符串,可能导致乱码、crash。原字符串为“%@”(%@),index 为 %@,命中的 ComposedCharacterSequence range 为 %@", NSStringFromSelector(originCMD), selfObject, @(selfObject.length), @(index), NSStringFromRange(range)];
NSAssert(NO, logString);
QMUILogWarn(@"QMUIStringSafety", @"%@", logString);
QMUIAssert(NO, @"QMUIStringSafety", @"%@", logString);
index = range.location;
}
}
Expand All @@ -238,8 +234,7 @@ + (void)qmuisafety_NSString {
BOOL isValidddatedRange = NSMaxRange(range) <= selfObject.length;
if (!isValidddatedRange) {
NSString *logString = [NSString stringWithFormat:@"%@ 传入了一个超过字符串长度的 range: %@,原字符串为: %@(%@)", NSStringFromSelector(originCMD), NSStringFromRange(range), selfObject, @(selfObject.length)];
NSAssert(NO, logString);
QMUILogWarn(@"QMUIStringSafety", @"%@", logString);
QMUIAssert(NO, @"QMUIStringSafety", @"%@", logString);
return @"";// 系统 substringWithRange: 返回值的标志是 nonnull
}
}
Expand All @@ -251,8 +246,7 @@ + (void)qmuisafety_NSString {
BOOL isValidddatedRange = range.length == 0 || NSEqualRanges(range, range2);
if (!isValidddatedRange) {
NSString *logString = [NSString stringWithFormat:@"试图在 ComposedCharacterSequence 中间用 %@ 裁剪字符串,可能导致乱码、crash。原字符串为“%@”(%@),range 为 %@,命中的 ComposedCharacterSequence range 为 %@", NSStringFromSelector(originCMD), selfObject, @(selfObject.length), NSStringFromRange(range), NSStringFromRange(range2)];
NSAssert(NO, logString);
QMUILogWarn(@"QMUIStringSafety", @"%@", logString);
QMUIAssert(NO, @"QMUIStringSafety", @"%@", logString);
range = range2;
}
}
Expand Down
15 changes: 11 additions & 4 deletions QMUIKit/UIKitExtensions/UIImage+QMUI.m
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,12 @@ - (UIImage *)qmui_imageWithTintColor:(UIColor *)tintColor {
CGContextSetFillColorWithColor(contextRef, tintColor.CGColor);
CGContextFillRect(contextRef, CGRectMakeWithSize(self.size));
}];
if ([NSStringFromClass(tintColor.class) containsString:@"QMUIThemeColor"]) {
QMUIAssert([NSStringFromClass(result.class) containsString:@"QMUIThemeImage"], @"UIImage (QMUI)", @"QMUIThemeColor 生成的图片却不是 QMUIThemeImage,可能是配置表应用的时机比 UIImage+QMUITheme 里重写 qmui_imageWithColor: 的时机还早,可能导致 theme 切换时无法刷新。");

SEL selector = NSSelectorFromString(@"qmui_generatorSupportsDynamicColor");
if ([NSStringFromClass(tintColor.class) containsString:@"QMUIThemeColor"] && [UIImage respondsToSelector:selector]) {
BOOL supports;
[UIImage.class qmui_performSelector:selector withPrimitiveReturnValue:&supports];
QMUIAssert(supports, @"UIImage (QMUI)", @"UIImage (QMUITheme) hook 尚未生效,QMUIThemeColor 生成的图片无法自动转成 QMUIThemeImage,可能导致 theme 切换时无法刷新。");
}
return result;
}
Expand Down Expand Up @@ -575,8 +579,11 @@ + (UIImage *)qmui_imageWithColor:(UIColor *)color size:(CGSize)size cornerRadius
CGContextFillRect(contextRef, CGRectMakeWithSize(size));
}
}];
if ([NSStringFromClass(color.class) containsString:@"QMUIThemeColor"]) {
QMUIAssert([NSStringFromClass(result.class) containsString:@"QMUIThemeImage"], @"UIImage (QMUI)", @"QMUIThemeColor 生成的图片却不是 QMUIThemeImage,可能是配置表应用的时机比 UIImage+QMUITheme 里重写 qmui_imageWithColor: 的时机还早,可能导致 theme 切换时无法刷新。");
SEL selector = NSSelectorFromString(@"qmui_generatorSupportsDynamicColor");
if ([NSStringFromClass(color.class) containsString:@"QMUIThemeColor"] && [UIImage respondsToSelector:selector]) {
BOOL supports;
[UIImage.class qmui_performSelector:selector withPrimitiveReturnValue:&supports];
QMUIAssert(supports, @"UIImage (QMUI)", @"UIImage (QMUITheme) hook 尚未生效,QMUIThemeColor 生成的图片无法自动转成 QMUIThemeImage,可能导致 theme 切换时无法刷新。");
}
return result;
}
Expand Down
6 changes: 5 additions & 1 deletion QMUIKit/UIKitExtensions/UISlider+QMUI.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,11 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, assign) NSUInteger qmui_step;

/// 在设置 qmui_numberOfSteps 时会创建对应个数的 QMUISliderStepControl,而通过这个 configuration block 可以配置每一个 stepControl 的属性
@property(nullable, nonatomic, copy) void (^qmui_stepControlConfiguration)(UISlider *slider, QMUISliderStepControl *stepControl, NSUInteger index);
@property(nullable, nonatomic, copy) void (^qmui_stepControlConfiguration)(__kindof UISlider *slider, QMUISliderStepControl *stepControl, NSUInteger index);

/// 当使用了 step 功能时,可通过这个 block 监听 step 的变化(只有 step 的值改变时才会触发),获取当前 step 的值请调用 slider.qmui_step,获取变化前的 step 值请访问参数 precedingStep。
/// @note 在系统的 UIControlEventValueChanged 里获取 slider.qmui_step 也可以,但因为 slider.continuous 默认是 YES,所以拖动过程中 UIControlEventValueChanged 会触发很多次,但 step 不一定有变化,所以用专门的 block 监听会更方便高效一点。
@property(nullable, nonatomic, copy) void (^qmui_stepDidChangeBlock)(__kindof UISlider *slider, NSUInteger precedingStep);
@end

@interface QMUISliderStepControl : UIControl
Expand Down

0 comments on commit 919fee5

Please sign in to comment.