在 SessionListViewController 中添加了对最近会话的日志输出。在 LuckyGiftWinningBannerView 和 BravoGiftBannerView 中引入了可配置的显示时间,注释掉了不再使用的代码。在 XPRoomFunctionContainerView 中优化了 hitTest 方法以增强用户交互体验,确保子视图的点击响应逻辑更加清晰。更新了 MicroView 中的表情加载逻辑,增加了对下载失败情况的处理。保持代码结构一致性。

This commit is contained in:
edwinQQQ
2025-06-09 15:52:34 +08:00
parent 5985b5701e
commit 8dab721de9
7 changed files with 167 additions and 142 deletions

View File

@@ -133,6 +133,7 @@ NSString * const kMessageShowReadDotKey = @"kMessageShowReadDotKey";
NIMLoadRecentSessionsOptions *options = [[NIMLoadRecentSessionsOptions alloc] init]; NIMLoadRecentSessionsOptions *options = [[NIMLoadRecentSessionsOptions alloc] init];
options.sortByStickTopInfos = YES; options.sortByStickTopInfos = YES;
[NIMSDK.sharedSDK.chatExtendManager loadRecentSessionsWithOptions:options completion:^(NSError * _Nullable error, NSArray<NIMRecentSession *> * _Nullable recentSessions) { [NIMSDK.sharedSDK.chatExtendManager loadRecentSessionsWithOptions:options completion:^(NSError * _Nullable error, NSArray<NIMRecentSession *> * _Nullable recentSessions) {
NSLog(@"%@", recentSessions);
}]; }];
} }

View File

@@ -103,10 +103,13 @@ exitCurrentRoom:(void(^)(void))exit {
[superView addSubview:bannerView]; [superView addSubview:bannerView];
[bannerView addNotification]; [bannerView addNotification];
NSInteger time = 3;
//#if DEBUG
// time = 3000;
//#endif
@kWeakify(bannerView); @kWeakify(bannerView);
[bannerView popEnterAnimation:^(BOOL finished) { [bannerView popEnterAnimation:^(BOOL finished) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(time * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
@kStrongify(bannerView); @kStrongify(bannerView);
[bannerView popLeaveAnimation:^(bool finished) { [bannerView popLeaveAnimation:^(bool finished) {
if (bannerView.completeDisplay) { if (bannerView.completeDisplay) {

View File

@@ -100,7 +100,7 @@ XPRoomGraffitiGiftAnimationViewDelegate
@property (nonatomic, strong) XPRoomAnimationHitView *bannerContainer; @property (nonatomic, strong) XPRoomAnimationHitView *bannerContainer;
/// --- /// ---
/// FIFO /// "队列" FIFO
@property (nonatomic, strong) NSMutableArray<NSDictionary *> *enterRoomAnimationQueue; @property (nonatomic, strong) NSMutableArray<NSDictionary *> *enterRoomAnimationQueue;
/// ///
@property (nonatomic, assign) BOOL isEnterRoomAnimating; @property (nonatomic, assign) BOOL isEnterRoomAnimating;
@@ -249,7 +249,7 @@ XPRoomGraffitiGiftAnimationViewDelegate
- (void)setupBanner { - (void)setupBanner {
_roomBannertModelsQueueV2 = [NSMutableArray array]; _roomBannertModelsQueueV2 = [NSMutableArray array];
[self addBnnerContainGesture]; // [self addBnnerContainGesture]; //
} }
- (void)setupCar { - (void)setupCar {
@@ -2050,6 +2050,8 @@ XPRoomGraffitiGiftAnimationViewDelegate
} }
#pragma mark - Gesture #pragma mark - Gesture
//
/*
- (void)addBnnerContainGesture { - (void)addBnnerContainGesture {
UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self
action:@selector(handleSwipe)]; action:@selector(handleSwipe)];
@@ -2061,6 +2063,7 @@ XPRoomGraffitiGiftAnimationViewDelegate
[self.bannerContainer addGestureRecognizer:swipe]; [self.bannerContainer addGestureRecognizer:swipe];
} }
*/
- (void)handleSwipe { - (void)handleSwipe {
[[NSNotificationCenter defaultCenter] postNotificationName:@"SwipeOutBanner" object:nil]; [[NSNotificationCenter defaultCenter] postNotificationName:@"SwipeOutBanner" object:nil];

View File

@@ -180,34 +180,45 @@
} }
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
for (NSInteger i = (self.subviews.count - 1) ; i >= 0 ; i--) { //
UIView * subView = [self.subviews xpSafeObjectAtIndex:i]; if (!self.userInteractionEnabled || self.hidden || self.alpha <= 0.01) {
CGPoint convertPoint = [subView convertPoint:point fromView:self]; return nil;
if (CGRectContainsPoint(subView.bounds, convertPoint)) { }
return [subView hitTest:convertPoint withEvent:event];
} //
} for (NSInteger i = (self.subviews.count - 1) ; i >= 0 ; i--) {
UIView *subView = [self.subviews xpSafeObjectAtIndex:i];
if (!subView) continue;
for (NSInteger i = (self.subviews.count - 1) ; i >= 0 ; i--) {
UIView * subView = [self.subviews objectAtIndex:i]; CGPoint convertPoint = [subView convertPoint:point fromView:self];
if (self.musicPlayView.superview && self.musicEnterButton.hidden == YES && ![subView isEqual:self.musicPlayView]) {
[UIView animateWithDuration:0.2 animations:^{ //
self.musicEnterButton.hidden = NO; if (CGRectContainsPoint(subView.bounds, convertPoint)) {
} completion:nil]; UIView *hitTestView = [subView hitTest:convertPoint withEvent:event];
if (hitTestView) {
POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter]; //
moveAnimation.fromValue = [NSValue valueWithCGPoint:self.musicPlayView.center]; if (self.musicPlayView.superview && self.musicEnterButton.hidden == YES && ![subView isEqual:self.musicPlayView]) {
moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-KScreenWidth, self.musicPlayView.center.y)]; [UIView animateWithDuration:0.2 animations:^{
moveAnimation.beginTime = CACurrentMediaTime(); self.musicEnterButton.hidden = NO;
moveAnimation.duration = 0.5; } completion:nil];
moveAnimation.repeatCount = 1;
moveAnimation.removedOnCompletion = YES; POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter];
[self.musicPlayView pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"]; moveAnimation.fromValue = [NSValue valueWithCGPoint:self.musicPlayView.center];
break; moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-KScreenWidth, self.musicPlayView.center.y)];
} moveAnimation.beginTime = CACurrentMediaTime();
} moveAnimation.duration = 0.5;
return nil; moveAnimation.repeatCount = 1;
moveAnimation.removedOnCompletion = YES;
[self.musicPlayView pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"];
}
return hitTestView;
}
}
}
// nil 穿
return nil;
} }
#pragma mark - Public Method #pragma mark - Public Method
- (void)hiddenSudGamePostionView { - (void)hiddenSudGamePostionView {

View File

@@ -54,9 +54,14 @@ exitCurrentRoom:(void(^)(void))exit {
[banner addNotification]; [banner addNotification];
[superView addSubview:banner]; [superView addSubview:banner];
NSInteger time = 3;
//#if DEBUG
// time = 3000;
//#endif
@kWeakify(banner); @kWeakify(banner);
[banner popEnterAnimation:^(BOOL finished) { [banner popEnterAnimation:^(BOOL finished) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(time * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
@kStrongify(banner); @kStrongify(banner);
[banner popLeaveAnimation:^(bool finished) { [banner popLeaveAnimation:^(bool finished) {
if (banner.completeDisplay) { if (banner.completeDisplay) {
@@ -127,12 +132,13 @@ exitCurrentRoom:(void(^)(void))exit {
self = [super initWithFrame:frame]; self = [super initWithFrame:frame];
if (self) { if (self) {
[self setupUI]; [self setupUI];
UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom]; self.userInteractionEnabled = NO;
[self addSubview:b]; // UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom];
[b mas_remakeConstraints:^(MASConstraintMaker *make) { // [self addSubview:b];
make.edges.mas_equalTo(self); // [b mas_remakeConstraints:^(MASConstraintMaker *make) {
}]; // make.edges.mas_equalTo(self);
[b addTarget:self action:@selector(handelTap) forControlEvents:UIControlEventTouchUpInside]; // }];
// [b addTarget:self action:@selector(handelTap) forControlEvents:UIControlEventTouchUpInside];
} }
return self; return self;
} }

View File

@@ -72,11 +72,11 @@ NSString * const kNewFacePath = @"MoliFaceCache";
NSString *path = [cachesPath stringByAppendingPathComponent:response.suggestedFilename]; NSString *path = [cachesPath stringByAppendingPathComponent:response.suggestedFilename];
return [NSURL fileURLWithPath:path]; return [NSURL fileURLWithPath:path];
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) { } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
if (error == nil) { if (error == nil) {
NSString *filePathStr = [filePath path]; NSString *filePathStr = [filePath path];
NSString *fileMD5Str = [self getFileMD5WithPath:filePathStr]; NSString *fileMD5Str = [self getFileMD5WithPath:filePathStr];
fileMD5Str = [fileMD5Str uppercaseString]; fileMD5Str = [fileMD5Str uppercaseString];
if (![self.zipMd5 isEqualToString:fileMD5Str]) { //MD5 if (![self.zipMd5 isEqualToString:fileMD5Str]) { //MD5
[self performSelector:@selector(downFaceData) withObject:nil afterDelay:3]; [self performSelector:@selector(downFaceData) withObject:nil afterDelay:3];
}else { }else {
// filePath使 // filePath使
@@ -275,13 +275,12 @@ done:
- (void)loadFace:(void(^)(NSString *path))fileBlock - (void)loadFace:(void(^)(NSString *path))fileBlock
withUrl:(NSString *)url { withUrl:(NSString *)url {
NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:kNewFacePath];
stringByAppendingPathComponent:kNewFacePath];
NSString *fileName = [url lastPathComponent]; NSString *fileName = [url lastPathComponent];
NSString *filePath = [cachePath stringByAppendingPathComponent:fileName]; NSString *filePath = [cachePath stringByAppendingPathComponent:fileName];
// 使
NSString *resultPath = [[NSFileManager defaultManager] fileExistsAtPath:filePath] ? filePath : nil; NSString *resultPath = [[NSFileManager defaultManager] fileExistsAtPath:filePath] ? filePath : nil;
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
if (fileBlock) { if (fileBlock) {
fileBlock(resultPath); fileBlock(resultPath);

View File

@@ -443,105 +443,107 @@
@kWeakify(self); @kWeakify(self);
[[XPRoomFaceTool shareFaceTool] loadFace:^(NSString * _Nonnull path) { [[XPRoomFaceTool shareFaceTool] loadFace:^(NSString * _Nonnull path) {
@kStrongify(self); @kStrongify(self);
SVGAParser *p = [[SVGAParser alloc] init]; if (![NSString isEmpty:path]) {
[p parseWithURL:[NSURL fileURLWithPath:path] completionBlock:^(SVGAVideoEntity * _Nullable videoItem) { SVGAParser *p = [[SVGAParser alloc] init];
self.faceSvgaImageView.videoItem = videoItem; [p parseWithURL:[NSURL fileURLWithPath:path] completionBlock:^(SVGAVideoEntity * _Nullable videoItem) {
[self.faceSvgaImageView startAnimation]; self.faceSvgaImageView.videoItem = videoItem;
} failureBlock:^(NSError * _Nullable error) { [self.faceSvgaImageView startAnimation];
[self.faceSvgaImageView stopAnimation]; } failureBlock:^(NSError * _Nullable error) {
}]; [self.faceSvgaImageView stopAnimation];
}];
} else {
// MARK: svga
// [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"MoliForceReloadFace"];
}
} withUrl:receiveInfo.svgaURL]; } withUrl:receiveInfo.svgaURL];
// [self.faceSvgaImageView setImageName:]; } else {
return; [self.faceImageView.layer removeAnimationForKey:@"face"];
UIImage * result;
if (receiveInfo.resultIndexes.count > 0) {
result = [self combineImageInOne:receiveInfo];
receiveInfo.resultImage = result;
}
RoomFaceInfoModel *configInfo = [[XPRoomFaceTool shareFaceTool] findFaceInfoById:receiveInfo.faceId];
if (receiveInfo.resultIndexes.count > 0) {
/*==================== ================= */
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
animation.duration = configInfo.animDuration / 1000.0;
animation.delegate = self;
animation.repeatCount = configInfo.animRepeatCount;
animation.removedOnCompletion = YES;
animation.calculationMode = kCAAnimationDiscrete;
//
NSMutableArray *faceArray = [NSMutableArray array];
for (int i = (short)configInfo.animStartPos; i <= (short)configInfo.animEndPos; i ++) {
UIImage *image = [[XPRoomFaceTool shareFaceTool] findFaceImageById:receiveInfo.faceId index:i];
if (image) {
CGImageRef cgimg = image.CGImage;
[faceArray addObject:(__bridge UIImage *)cgimg];
}else {
break;
}
}
if (faceArray.count > 0) {
animation.values = faceArray;
}else {
return;
}
/*==================== ================= */
CAKeyframeAnimation *resultAnimation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
resultAnimation.duration = 3;
resultAnimation.delegate = self;
resultAnimation.beginTime = configInfo.animRepeatCount * configInfo.animDuration / 1000.0;
//
NSMutableArray *resultArray = [NSMutableArray array];
if (receiveInfo.resultImage) {
[resultArray addObject:(__bridge UIImage *)receiveInfo.resultImage.CGImage];
}else {
return;
}
if (resultArray.count > 0) {
resultAnimation.values = resultArray;
}else {
return;
}
resultAnimation.removedOnCompletion = YES;
CAAnimationGroup *group = [CAAnimationGroup animation];
group.animations = @[animation,resultAnimation];
group.duration = 3 + (configInfo.animDuration / 1000.0) * configInfo.animRepeatCount;
group.delegate = self;
[self.faceImageView.layer addAnimation:group forKey:@"face"];
} else {
/*==================== ================= */
//CAKeyframeAnimation
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
animation.duration = configInfo.animDuration / 1000.0;
animation.delegate = self;
animation.repeatCount = configInfo.animRepeatCount;
animation.removedOnCompletion = YES;
animation.calculationMode = kCAAnimationDiscrete;
//
NSMutableArray *faceArray = [NSMutableArray array];
for (int i = (short)configInfo.animStartPos; i <= (short)configInfo.animEndPos; i ++) {
UIImage *image = [[XPRoomFaceTool shareFaceTool] findFaceImageById:receiveInfo.faceId index:i];;
if (image) {
CGImageRef cgimg = image.CGImage;
[faceArray addObject:(__bridge UIImage *)cgimg];
}else {
break;
}
}
if (faceArray.count > 0) {
animation.values = [faceArray copy];
[self.faceImageView.layer addAnimation:animation forKey:@"face"];
}
}
} }
[self.faceImageView.layer removeAnimationForKey:@"face"];
UIImage * result;
if (receiveInfo.resultIndexes.count > 0) {
result = [self combineImageInOne:receiveInfo];
receiveInfo.resultImage = result;
}
RoomFaceInfoModel *configInfo = [[XPRoomFaceTool shareFaceTool] findFaceInfoById:receiveInfo.faceId];
if (receiveInfo.resultIndexes.count > 0) {
/*==================== ================= */
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
animation.duration = configInfo.animDuration / 1000.0;
animation.delegate = self;
animation.repeatCount = configInfo.animRepeatCount;
animation.removedOnCompletion = YES;
animation.calculationMode = kCAAnimationDiscrete;
//
NSMutableArray *faceArray = [NSMutableArray array];
for (int i = (short)configInfo.animStartPos; i <= (short)configInfo.animEndPos; i ++) {
UIImage *image = [[XPRoomFaceTool shareFaceTool] findFaceImageById:receiveInfo.faceId index:i];
if (image) {
CGImageRef cgimg = image.CGImage;
[faceArray addObject:(__bridge UIImage *)cgimg];
}else {
break;
}
}
if (faceArray.count > 0) {
animation.values = faceArray;
}else {
return;
}
/*==================== ================= */
CAKeyframeAnimation *resultAnimation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
resultAnimation.duration = 3;
resultAnimation.delegate = self;
resultAnimation.beginTime = configInfo.animRepeatCount * configInfo.animDuration / 1000.0;
//
NSMutableArray *resultArray = [NSMutableArray array];
if (receiveInfo.resultImage) {
[resultArray addObject:(__bridge UIImage *)receiveInfo.resultImage.CGImage];
}else {
return;
}
if (resultArray.count > 0) {
resultAnimation.values = resultArray;
}else {
return;
}
resultAnimation.removedOnCompletion = YES;
CAAnimationGroup *group = [CAAnimationGroup animation];
group.animations = @[animation,resultAnimation];
group.duration = 3 + (configInfo.animDuration / 1000.0) * configInfo.animRepeatCount;
group.delegate = self;
[self.faceImageView.layer addAnimation:group forKey:@"face"];
} else {
/*==================== ================= */
//CAKeyframeAnimation
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
animation.duration = configInfo.animDuration / 1000.0;
animation.delegate = self;
animation.repeatCount = configInfo.animRepeatCount;
animation.removedOnCompletion = YES;
animation.calculationMode = kCAAnimationDiscrete;
//
NSMutableArray *faceArray = [NSMutableArray array];
for (int i = (short)configInfo.animStartPos; i <= (short)configInfo.animEndPos; i ++) {
UIImage *image = [[XPRoomFaceTool shareFaceTool] findFaceImageById:receiveInfo.faceId index:i];;
if (image) {
CGImageRef cgimg = image.CGImage;
[faceArray addObject:(__bridge UIImage *)cgimg];
}else {
break;
}
}
if (faceArray.count > 0) {
animation.values = [faceArray copy];
[self.faceImageView.layer addAnimation:animation forKey:@"face"];
}
}
} }
/** /**