|
|
@@ -111,6 +111,23 @@
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+#pragma mark - Cell
|
|
|
+// 添加一个方法来处理 Cell 重用
|
|
|
+- (void)prepareForReuse {
|
|
|
+ [self stopShimmer];
|
|
|
+
|
|
|
+ // 重新创建必要的对象
|
|
|
+ self.shimmerLabel = [[UILabel alloc] initWithFrame:self.bounds];
|
|
|
+ [self addSubview:self.shimmerLabel];
|
|
|
+ self.shimmerLayer = [CAGradientLayer layer];
|
|
|
+
|
|
|
+ // 恢复原始状态
|
|
|
+ [super setTextColor:self.originalTextColor];
|
|
|
+ [super setText:self.originalText];
|
|
|
+ [super setAttributedText:self.originalAttributedText];
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
#pragma mark - Override Properties
|
|
|
|
|
|
/// 重写setText方法,确保动画状态正确
|
|
|
@@ -229,12 +246,21 @@
|
|
|
- (void)stopShimmer {
|
|
|
if (!self.shimmerIsPlaying) return;
|
|
|
|
|
|
- [self.shimmerLayer removeAllAnimations];
|
|
|
- [self.layer removeAllAnimations];
|
|
|
- [self.shimmerLayer removeFromSuperlayer];
|
|
|
- [self.shimmerLabel removeFromSuperview];
|
|
|
- self.layer.mask = nil;
|
|
|
- self.shimmerLabel.layer.mask = nil;
|
|
|
+ @try {
|
|
|
+ [self.shimmerLayer removeAllAnimations];
|
|
|
+ [self.layer removeAllAnimations];
|
|
|
+ self.layer.mask = nil;
|
|
|
+ if (self.shimmerLabel.layer) {
|
|
|
+ self.shimmerLabel.layer.mask = nil;
|
|
|
+ }
|
|
|
+ [self.shimmerLayer removeFromSuperlayer];
|
|
|
+// [self.shimmerLabel removeFromSuperview];
|
|
|
+ self.shimmerLabel.hidden = YES;
|
|
|
+
|
|
|
+ } @catch (NSException *exception) {
|
|
|
+ NSLog(@"MOShimmerLabel stopShimmer exception: %@", exception);
|
|
|
+ }
|
|
|
+
|
|
|
self.shimmerIsPlaying = NO;
|
|
|
}
|
|
|
|
|
|
@@ -243,8 +269,34 @@
|
|
|
/// 开始闪光动画
|
|
|
/// @param force 是否强制重新开始动画
|
|
|
- (void)startShimmerWithForce:(BOOL)force {
|
|
|
- if (!force && self.shimmerIsPlaying) return;
|
|
|
- self.shimmerIsPlaying = YES;
|
|
|
+
|
|
|
+
|
|
|
+ @try {
|
|
|
+ if (!force && self.shimmerIsPlaying) return;
|
|
|
+ if (!self.window || self.bounds.size.width <= 0) return; // 添加显示检查
|
|
|
+
|
|
|
+ // 确保必要组件存在
|
|
|
+ if (!self.shimmerConfig) {
|
|
|
+ self.shimmerConfig = [[ShimmerLabelConfig alloc] init];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 确保基础组件存在
|
|
|
+ if (!self.shimmerLabel) {
|
|
|
+ self.shimmerLabel = [[UILabel alloc] initWithFrame:self.bounds];
|
|
|
+ [self addSubview:self.shimmerLabel];
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!self.shimmerLayer) {
|
|
|
+ self.shimmerLayer = [CAGradientLayer layer];
|
|
|
+ }
|
|
|
+
|
|
|
+ self.shimmerIsPlaying = YES;
|
|
|
+ // ... 原有的动画设置代码 ...
|
|
|
+ } @catch (NSException *exception) {
|
|
|
+ NSLog(@"MOShimmerLabel startShimmerWithForce exception: %@", exception);
|
|
|
+ }
|
|
|
+
|
|
|
+ self.shimmerLabel.hidden = NO;
|
|
|
|
|
|
CAAnimation *animation;
|
|
|
switch (self.shimmerConfig.shimmerStyle) {
|
|
|
@@ -664,15 +716,43 @@
|
|
|
if (!newWindow) {
|
|
|
[self stopShimmer];
|
|
|
}
|
|
|
+ else {
|
|
|
+ // Cell 显示时,如果需要动画效果则重新开始
|
|
|
+ if (self.shimmerConfig.shimmerStyle != ShimmerStyleNone) {
|
|
|
+ [self startShimmerWithForce:YES];
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- (void)didMoveToWindow {
|
|
|
[super didMoveToWindow];
|
|
|
|
|
|
- if (self.window &&
|
|
|
- self.shimmerConfig.shimmerStyle != ShimmerStyleNone &&
|
|
|
- !self.shimmerIsPlaying) {
|
|
|
- [self startShimmerWithForce:NO];
|
|
|
+ @try {
|
|
|
+ // 添加安全检查
|
|
|
+ if (!self.shimmerConfig) {
|
|
|
+ self.shimmerConfig = [[ShimmerLabelConfig alloc] init];
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!self.shimmerLabel) {
|
|
|
+ self.shimmerLabel = [[UILabel alloc] initWithFrame:self.bounds];
|
|
|
+ [self addSubview:self.shimmerLabel];
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!self.shimmerLayer) {
|
|
|
+ self.shimmerLayer = [CAGradientLayer layer];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 确保在合适的时机开始动画
|
|
|
+ if (self.window &&
|
|
|
+ self.shimmerConfig.shimmerStyle != ShimmerStyleNone &&
|
|
|
+ !self.shimmerIsPlaying &&
|
|
|
+ self.bounds.size.width > 0) {
|
|
|
+ dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
+ [self startShimmerWithForce:NO];
|
|
|
+ });
|
|
|
+ }
|
|
|
+ } @catch (NSException *exception) {
|
|
|
+ NSLog(@"MOShimmerLabel didMoveToWindow exception: %@", exception);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -699,32 +779,38 @@
|
|
|
- (void)layoutSubviews {
|
|
|
[super layoutSubviews];
|
|
|
|
|
|
- if (self.bounds.size.width <= 0) return;
|
|
|
-
|
|
|
- BOOL needForceShimmer = !CGSizeEqualToSize(self.bounds.size, self.shimmerLastSize);
|
|
|
- self.shimmerLastSize = self.bounds.size;
|
|
|
-
|
|
|
- // 同步 shimmerLabel 的基本属性
|
|
|
- self.shimmerLabel.frame = self.bounds;
|
|
|
- self.shimmerLabel.font = self.font;
|
|
|
- self.shimmerLabel.textAlignment = self.textAlignment;
|
|
|
- self.shimmerLabel.numberOfLines = self.numberOfLines;
|
|
|
+ if (self.bounds.size.width <= 0 || !self.window) return;
|
|
|
|
|
|
- if (self.shimmerConfig.shimmerStyle == ShimmerStyleColorsFlow) {
|
|
|
- self.shimmerLayer.frame = CGRectMake(-self.shimmerConfig.shimmerWidth, 0,
|
|
|
- [self rawWidth] + self.shimmerConfig.shimmerWidth * 2,
|
|
|
- self.bounds.size.height);
|
|
|
- self.shimmerLabel.frame = CGRectMake(self.shimmerConfig.shimmerWidth, 0,
|
|
|
- [self rawMaskWidth],
|
|
|
- self.bounds.size.height);
|
|
|
- } else {
|
|
|
- self.shimmerLayer.frame = CGRectMake(0, 0, [self rawWidth], self.bounds.size.height);
|
|
|
- self.shimmerLabel.frame = CGRectMake(0, 0, [self rawMaskWidth], self.bounds.size.height);
|
|
|
+ @try {
|
|
|
+ BOOL needForceShimmer = !CGSizeEqualToSize(self.bounds.size, self.shimmerLastSize);
|
|
|
+ self.shimmerLastSize = self.bounds.size;
|
|
|
+
|
|
|
+ // 同步 shimmerLabel 的基本属性
|
|
|
+ self.shimmerLabel.frame = self.bounds;
|
|
|
+ self.shimmerLabel.font = self.font;
|
|
|
+ self.shimmerLabel.textAlignment = self.textAlignment;
|
|
|
+ self.shimmerLabel.numberOfLines = self.numberOfLines;
|
|
|
+
|
|
|
+ if (self.shimmerConfig.shimmerStyle == ShimmerStyleColorsFlow) {
|
|
|
+ self.shimmerLayer.frame = CGRectMake(-self.shimmerConfig.shimmerWidth, 0,
|
|
|
+ [self rawWidth] + self.shimmerConfig.shimmerWidth * 2,
|
|
|
+ self.bounds.size.height);
|
|
|
+ self.shimmerLabel.frame = CGRectMake(self.shimmerConfig.shimmerWidth, 0,
|
|
|
+ [self rawMaskWidth],
|
|
|
+ self.bounds.size.height);
|
|
|
+ } else {
|
|
|
+ self.shimmerLayer.frame = CGRectMake(0, 0, [self rawWidth], self.bounds.size.height);
|
|
|
+ self.shimmerLabel.frame = CGRectMake(0, 0, [self rawMaskWidth], self.bounds.size.height);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (self.window && self.shimmerConfig.shimmerStyle != ShimmerStyleNone) {
|
|
|
+ [self startShimmerWithForce:needForceShimmer];
|
|
|
+ }
|
|
|
+ } @catch (NSException *exception) {
|
|
|
+ NSLog(@"MOShimmerLabel layoutSubviews exception: %@", exception);
|
|
|
}
|
|
|
|
|
|
- if (self.window) {
|
|
|
- [self startShimmerWithForce:needForceShimmer];
|
|
|
- }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
/// 处理bounds和frame变化
|