在 SessionListViewController 中添加了对最近会话的日志输出。在 LuckyGiftWinningBannerView 和 BravoGiftBannerView 中引入了可配置的显示时间,注释掉了不再使用的代码。在 XPRoomFunctionContainerView 中优化了 hitTest 方法以增强用户交互体验,确保子视图的点击响应逻辑更加清晰。更新了 MicroView 中的表情加载逻辑,增加了对下载失败情况的处理。保持代码结构一致性。
This commit is contained in:
@@ -133,6 +133,7 @@ NSString * const kMessageShowReadDotKey = @"kMessageShowReadDotKey";
|
||||
NIMLoadRecentSessionsOptions *options = [[NIMLoadRecentSessionsOptions alloc] init];
|
||||
options.sortByStickTopInfos = YES;
|
||||
[NIMSDK.sharedSDK.chatExtendManager loadRecentSessionsWithOptions:options completion:^(NSError * _Nullable error, NSArray<NIMRecentSession *> * _Nullable recentSessions) {
|
||||
NSLog(@"%@", recentSessions);
|
||||
}];
|
||||
}
|
||||
|
||||
|
@@ -103,10 +103,13 @@ exitCurrentRoom:(void(^)(void))exit {
|
||||
[superView addSubview:bannerView];
|
||||
|
||||
[bannerView addNotification];
|
||||
|
||||
NSInteger time = 3;
|
||||
//#if DEBUG
|
||||
// time = 3000;
|
||||
//#endif
|
||||
@kWeakify(bannerView);
|
||||
[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);
|
||||
[bannerView popLeaveAnimation:^(bool finished) {
|
||||
if (bannerView.completeDisplay) {
|
||||
|
@@ -100,7 +100,7 @@ XPRoomGraffitiGiftAnimationViewDelegate
|
||||
@property (nonatomic, strong) XPRoomAnimationHitView *bannerContainer;
|
||||
|
||||
/// --- 进场
|
||||
/// 存放进房待播放动画的“队列”(这里用数组模拟队列 FIFO)
|
||||
/// 存放进房待播放动画的"队列"(这里用数组模拟队列 FIFO)
|
||||
@property (nonatomic, strong) NSMutableArray<NSDictionary *> *enterRoomAnimationQueue;
|
||||
/// 标记当前是否有进房动画在执行
|
||||
@property (nonatomic, assign) BOOL isEnterRoomAnimating;
|
||||
@@ -249,7 +249,7 @@ XPRoomGraffitiGiftAnimationViewDelegate
|
||||
|
||||
- (void)setupBanner {
|
||||
_roomBannertModelsQueueV2 = [NSMutableArray array];
|
||||
[self addBnnerContainGesture];
|
||||
// [self addBnnerContainGesture]; // 注释掉这行
|
||||
}
|
||||
|
||||
- (void)setupCar {
|
||||
@@ -2050,6 +2050,8 @@ XPRoomGraffitiGiftAnimationViewDelegate
|
||||
}
|
||||
|
||||
#pragma mark - Gesture
|
||||
// 注释掉整个方法
|
||||
/*
|
||||
- (void)addBnnerContainGesture {
|
||||
UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self
|
||||
action:@selector(handleSwipe)];
|
||||
@@ -2061,6 +2063,7 @@ XPRoomGraffitiGiftAnimationViewDelegate
|
||||
|
||||
[self.bannerContainer addGestureRecognizer:swipe];
|
||||
}
|
||||
*/
|
||||
|
||||
- (void)handleSwipe {
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"SwipeOutBanner" object:nil];
|
||||
|
@@ -180,34 +180,45 @@
|
||||
}
|
||||
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
|
||||
for (NSInteger i = (self.subviews.count - 1) ; i >= 0 ; i--) {
|
||||
UIView * subView = [self.subviews xpSafeObjectAtIndex:i];
|
||||
CGPoint convertPoint = [subView convertPoint:point fromView:self];
|
||||
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 objectAtIndex:i];
|
||||
if (self.musicPlayView.superview && self.musicEnterButton.hidden == YES && ![subView isEqual:self.musicPlayView]) {
|
||||
[UIView animateWithDuration:0.2 animations:^{
|
||||
self.musicEnterButton.hidden = NO;
|
||||
} completion:nil];
|
||||
|
||||
POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter];
|
||||
moveAnimation.fromValue = [NSValue valueWithCGPoint:self.musicPlayView.center];
|
||||
moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-KScreenWidth, self.musicPlayView.center.y)];
|
||||
moveAnimation.beginTime = CACurrentMediaTime();
|
||||
moveAnimation.duration = 0.5;
|
||||
moveAnimation.repeatCount = 1;
|
||||
moveAnimation.removedOnCompletion = YES;
|
||||
[self.musicPlayView pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
// 先检查自身状态
|
||||
if (!self.userInteractionEnabled || self.hidden || self.alpha <= 0.01) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
// 从后往前遍历子视图,检查是否有子视图能响应
|
||||
for (NSInteger i = (self.subviews.count - 1) ; i >= 0 ; i--) {
|
||||
UIView *subView = [self.subviews xpSafeObjectAtIndex:i];
|
||||
if (!subView) continue;
|
||||
|
||||
CGPoint convertPoint = [subView convertPoint:point fromView:self];
|
||||
|
||||
// 只有点击在子视图的实际区域内才继续处理
|
||||
if (CGRectContainsPoint(subView.bounds, convertPoint)) {
|
||||
UIView *hitTestView = [subView hitTest:convertPoint withEvent:event];
|
||||
if (hitTestView) {
|
||||
// 保留音乐播放器的特殊逻辑
|
||||
if (self.musicPlayView.superview && self.musicEnterButton.hidden == YES && ![subView isEqual:self.musicPlayView]) {
|
||||
[UIView animateWithDuration:0.2 animations:^{
|
||||
self.musicEnterButton.hidden = NO;
|
||||
} completion:nil];
|
||||
|
||||
POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter];
|
||||
moveAnimation.fromValue = [NSValue valueWithCGPoint:self.musicPlayView.center];
|
||||
moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-KScreenWidth, self.musicPlayView.center.y)];
|
||||
moveAnimation.beginTime = CACurrentMediaTime();
|
||||
moveAnimation.duration = 0.5;
|
||||
moveAnimation.repeatCount = 1;
|
||||
moveAnimation.removedOnCompletion = YES;
|
||||
[self.musicPlayView pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"];
|
||||
}
|
||||
|
||||
return hitTestView;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有子视图能响应,返回 nil 实现点击穿透
|
||||
return nil;
|
||||
}
|
||||
#pragma mark - Public Method
|
||||
- (void)hiddenSudGamePostionView {
|
||||
|
@@ -54,9 +54,14 @@ exitCurrentRoom:(void(^)(void))exit {
|
||||
[banner addNotification];
|
||||
[superView addSubview:banner];
|
||||
|
||||
NSInteger time = 3;
|
||||
//#if DEBUG
|
||||
// time = 3000;
|
||||
//#endif
|
||||
|
||||
@kWeakify(banner);
|
||||
[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);
|
||||
[banner popLeaveAnimation:^(bool finished) {
|
||||
if (banner.completeDisplay) {
|
||||
@@ -127,12 +132,13 @@ exitCurrentRoom:(void(^)(void))exit {
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
[self setupUI];
|
||||
UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[self addSubview:b];
|
||||
[b mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.edges.mas_equalTo(self);
|
||||
}];
|
||||
[b addTarget:self action:@selector(handelTap) forControlEvents:UIControlEventTouchUpInside];
|
||||
self.userInteractionEnabled = NO;
|
||||
// UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
// [self addSubview:b];
|
||||
// [b mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
// make.edges.mas_equalTo(self);
|
||||
// }];
|
||||
// [b addTarget:self action:@selector(handelTap) forControlEvents:UIControlEventTouchUpInside];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
@@ -72,11 +72,11 @@ NSString * const kNewFacePath = @"MoliFaceCache";
|
||||
NSString *path = [cachesPath stringByAppendingPathComponent:response.suggestedFilename];
|
||||
return [NSURL fileURLWithPath:path];
|
||||
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
|
||||
if (error == nil) {
|
||||
if (error == nil) {
|
||||
NSString *filePathStr = [filePath path];
|
||||
NSString *fileMD5Str = [self getFileMD5WithPath:filePathStr];
|
||||
fileMD5Str = [fileMD5Str uppercaseString];
|
||||
if (![self.zipMd5 isEqualToString:fileMD5Str]) { //MD5校验 如果不相等就重新下载
|
||||
if (![self.zipMd5 isEqualToString:fileMD5Str]) { //MD5校验 如果不相等就重新下载
|
||||
[self performSelector:@selector(downFaceData) withObject:nil afterDelay:3];
|
||||
}else {
|
||||
// filePath就是你下载文件的位置,你可以解压,也可以直接拿来使用
|
||||
@@ -275,13 +275,12 @@ done:
|
||||
|
||||
- (void)loadFace:(void(^)(NSString *path))fileBlock
|
||||
withUrl:(NSString *)url {
|
||||
NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject
|
||||
stringByAppendingPathComponent:kNewFacePath];
|
||||
NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:kNewFacePath];
|
||||
NSString *fileName = [url lastPathComponent];
|
||||
NSString *filePath = [cachePath stringByAppendingPathComponent:fileName];
|
||||
|
||||
// 确认缓存的地址和实际使用的地址
|
||||
NSString *resultPath = [[NSFileManager defaultManager] fileExistsAtPath:filePath] ? filePath : nil;
|
||||
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (fileBlock) {
|
||||
fileBlock(resultPath);
|
||||
|
@@ -443,105 +443,107 @@
|
||||
@kWeakify(self);
|
||||
[[XPRoomFaceTool shareFaceTool] loadFace:^(NSString * _Nonnull path) {
|
||||
@kStrongify(self);
|
||||
SVGAParser *p = [[SVGAParser alloc] init];
|
||||
[p parseWithURL:[NSURL fileURLWithPath:path] completionBlock:^(SVGAVideoEntity * _Nullable videoItem) {
|
||||
self.faceSvgaImageView.videoItem = videoItem;
|
||||
[self.faceSvgaImageView startAnimation];
|
||||
} failureBlock:^(NSError * _Nullable error) {
|
||||
[self.faceSvgaImageView stopAnimation];
|
||||
}];
|
||||
if (![NSString isEmpty:path]) {
|
||||
SVGAParser *p = [[SVGAParser alloc] init];
|
||||
[p parseWithURL:[NSURL fileURLWithPath:path] completionBlock:^(SVGAVideoEntity * _Nullable videoItem) {
|
||||
self.faceSvgaImageView.videoItem = videoItem;
|
||||
[self.faceSvgaImageView startAnimation];
|
||||
} failureBlock:^(NSError * _Nullable error) {
|
||||
[self.faceSvgaImageView stopAnimation];
|
||||
}];
|
||||
} else {
|
||||
// MARK: 可能存在下载 svga 不成功情况,需要区别新旧的表情
|
||||
// [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"MoliForceReloadFace"];
|
||||
}
|
||||
} withUrl:receiveInfo.svgaURL];
|
||||
// [self.faceSvgaImageView setImageName:];
|
||||
return;
|
||||
} else {
|
||||
[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"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user