feat: 完成 CP 相关动效
This commit is contained in:
@@ -503,6 +503,14 @@
|
||||
5412E0FD2C52512100FDD668 /* RoomBottomEntranceModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 5412E0FC2C52512100FDD668 /* RoomBottomEntranceModel.m */; };
|
||||
541DD9552C1EDEFB00B616C4 /* XPHomePagingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 541DD9542C1EDEFB00B616C4 /* XPHomePagingViewController.m */; };
|
||||
544A36352C94160F00CA7858 /* RoomMenuBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 544A36342C94160F00CA7858 /* RoomMenuBar.m */; };
|
||||
544B19B02CA1299500885BEB /* CPBindingAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 544B19AF2CA1299500885BEB /* CPBindingAnimation.m */; };
|
||||
544B19B32CA129A800885BEB /* CPLevelUpAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 544B19B22CA129A800885BEB /* CPLevelUpAnimation.m */; };
|
||||
544B19B62CA14A7100885BEB /* CPGiftBanner.m in Sources */ = {isa = PBXBuildFile; fileRef = 544B19B52CA14A7100885BEB /* CPGiftBanner.m */; };
|
||||
544B19BC2CA169BE00885BEB /* level up 3.svga in Resources */ = {isa = PBXBuildFile; fileRef = 544B19B92CA169BE00885BEB /* level up 3.svga */; };
|
||||
544B19BD2CA169BE00885BEB /* level up 4.svga in Resources */ = {isa = PBXBuildFile; fileRef = 544B19BA2CA169BE00885BEB /* level up 4.svga */; };
|
||||
544B19BE2CA169BE00885BEB /* level up 5.svga in Resources */ = {isa = PBXBuildFile; fileRef = 544B19BB2CA169BE00885BEB /* level up 5.svga */; };
|
||||
544B19BF2CA169BE00885BEB /* level up 1.svga in Resources */ = {isa = PBXBuildFile; fileRef = 544B19B72CA169BE00885BEB /* level up 1.svga */; };
|
||||
544B19C02CA169BE00885BEB /* level up 2.svga in Resources */ = {isa = PBXBuildFile; fileRef = 544B19B82CA169BE00885BEB /* level up 2.svga */; };
|
||||
5456F3C82C6EF962000E1805 /* VIPCenterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5456F3C72C6EF962000E1805 /* VIPCenterViewController.m */; };
|
||||
5458319D2C2AE09300364026 /* XPRoomTypeSelectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5458319C2C2AE09300364026 /* XPRoomTypeSelectionViewController.m */; };
|
||||
545831A02C2AEFAF00364026 /* TenMicStageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5458319F2C2AEFAF00364026 /* TenMicStageView.m */; };
|
||||
@@ -2556,6 +2564,17 @@
|
||||
541DD9542C1EDEFB00B616C4 /* XPHomePagingViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPHomePagingViewController.m; sourceTree = "<group>"; };
|
||||
544A36332C94160F00CA7858 /* RoomMenuBar.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RoomMenuBar.h; sourceTree = "<group>"; };
|
||||
544A36342C94160F00CA7858 /* RoomMenuBar.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RoomMenuBar.m; sourceTree = "<group>"; };
|
||||
544B19AE2CA1299500885BEB /* CPBindingAnimation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPBindingAnimation.h; sourceTree = "<group>"; };
|
||||
544B19AF2CA1299500885BEB /* CPBindingAnimation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPBindingAnimation.m; sourceTree = "<group>"; };
|
||||
544B19B12CA129A800885BEB /* CPLevelUpAnimation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPLevelUpAnimation.h; sourceTree = "<group>"; };
|
||||
544B19B22CA129A800885BEB /* CPLevelUpAnimation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPLevelUpAnimation.m; sourceTree = "<group>"; };
|
||||
544B19B42CA14A7100885BEB /* CPGiftBanner.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPGiftBanner.h; sourceTree = "<group>"; };
|
||||
544B19B52CA14A7100885BEB /* CPGiftBanner.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPGiftBanner.m; sourceTree = "<group>"; };
|
||||
544B19B72CA169BE00885BEB /* level up 1.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = "level up 1.svga"; sourceTree = "<group>"; };
|
||||
544B19B82CA169BE00885BEB /* level up 2.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = "level up 2.svga"; sourceTree = "<group>"; };
|
||||
544B19B92CA169BE00885BEB /* level up 3.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = "level up 3.svga"; sourceTree = "<group>"; };
|
||||
544B19BA2CA169BE00885BEB /* level up 4.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = "level up 4.svga"; sourceTree = "<group>"; };
|
||||
544B19BB2CA169BE00885BEB /* level up 5.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = "level up 5.svga"; sourceTree = "<group>"; };
|
||||
5456F3C62C6EF962000E1805 /* VIPCenterViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VIPCenterViewController.h; sourceTree = "<group>"; };
|
||||
5456F3C72C6EF962000E1805 /* VIPCenterViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VIPCenterViewController.m; sourceTree = "<group>"; };
|
||||
5458319B2C2AE09300364026 /* XPRoomTypeSelectionViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPRoomTypeSelectionViewController.h; sourceTree = "<group>"; };
|
||||
@@ -6487,6 +6506,11 @@
|
||||
54FFD3802C9BD12600DE61E5 /* cp */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
544B19B72CA169BE00885BEB /* level up 1.svga */,
|
||||
544B19B82CA169BE00885BEB /* level up 2.svga */,
|
||||
544B19B92CA169BE00885BEB /* level up 3.svga */,
|
||||
544B19BA2CA169BE00885BEB /* level up 4.svga */,
|
||||
544B19BB2CA169BE00885BEB /* level up 5.svga */,
|
||||
54B9C6FA2C9DA4C4003F1CC5 /* CP绑定.mp4 */,
|
||||
54B9C6F42C9D8D05003F1CC5 /* 3.mp4 */,
|
||||
54B9C6F52C9D8D05003F1CC5 /* 4.mp4 */,
|
||||
@@ -10932,6 +10956,12 @@
|
||||
children = (
|
||||
54AE7E122C9AD98C006D2BE2 /* CPCard.h */,
|
||||
54AE7E132C9AD9A6006D2BE2 /* CPCard.m */,
|
||||
544B19B42CA14A7100885BEB /* CPGiftBanner.h */,
|
||||
544B19B52CA14A7100885BEB /* CPGiftBanner.m */,
|
||||
544B19AE2CA1299500885BEB /* CPBindingAnimation.h */,
|
||||
544B19AF2CA1299500885BEB /* CPBindingAnimation.m */,
|
||||
544B19B12CA129A800885BEB /* CPLevelUpAnimation.h */,
|
||||
544B19B22CA129A800885BEB /* CPLevelUpAnimation.m */,
|
||||
E87E545229AA05EA00EBE52B /* XPFootPrintNavView.h */,
|
||||
E87E545329AA05EA00EBE52B /* XPFootPrintNavView.m */,
|
||||
E8B846CC26FDD93D00A777FE /* Recharge */,
|
||||
@@ -11229,6 +11259,11 @@
|
||||
E80EC87728ACD84000D133C5 /* emoji_148@2x.png in Resources */,
|
||||
E80EC81928ACD84000D133C5 /* emoji_80@2x.png in Resources */,
|
||||
237701192BD6143700D661F1 /* pi_happy_egg_smash.svga in Resources */,
|
||||
544B19BC2CA169BE00885BEB /* level up 3.svga in Resources */,
|
||||
544B19BD2CA169BE00885BEB /* level up 4.svga in Resources */,
|
||||
544B19BE2CA169BE00885BEB /* level up 5.svga in Resources */,
|
||||
544B19BF2CA169BE00885BEB /* level up 1.svga in Resources */,
|
||||
544B19C02CA169BE00885BEB /* level up 2.svga in Resources */,
|
||||
E80EC8B328ACD84100D133C5 /* emoji_115@2x.png in Resources */,
|
||||
54FFD3812C9BD12600DE61E5 /* 4.svga in Resources */,
|
||||
54FFD3822C9BD12600DE61E5 /* 1.svga in Resources */,
|
||||
@@ -11663,6 +11698,7 @@
|
||||
54F469382C29C3B400A83655 /* XPMineAlbumTableViewCell.m in Sources */,
|
||||
23E9EAA12A84C53900B792F2 /* TTNewAlertView.m in Sources */,
|
||||
238B37BC2AC55A2C00BFC9D5 /* XPTreasureFairySendView.m in Sources */,
|
||||
544B19B02CA1299500885BEB /* CPBindingAnimation.m in Sources */,
|
||||
E8DEC9A12764A5D20078CB70 /* XPRoomMoreItemModel.m in Sources */,
|
||||
E80EC81028ACD84000D133C5 /* QExtendBoardView.m in Sources */,
|
||||
9B87B3CD2926473D00085110 /* XPSessionListHeadFriendCell.m in Sources */,
|
||||
@@ -12082,6 +12118,7 @@
|
||||
9B6B3AAB278C2EA7005551EC /* XPRoomNobleLevelUpView.m in Sources */,
|
||||
E85E7B302A4EB0D300B6D00A /* XPGuildIncomeHeaderView.m in Sources */,
|
||||
E85E7B222A4EB0D300B6D00A /* XPMineGuildIncomeRecordViewController.m in Sources */,
|
||||
544B19B32CA129A800885BEB /* CPLevelUpAnimation.m in Sources */,
|
||||
9BD2ECD5288F838200F5CD9A /* XPMineFootPrintPresenter.m in Sources */,
|
||||
9B1B72BF2800422E003FACE9 /* XPAnchorPKRuleView.m in Sources */,
|
||||
54F469352C29711400A83655 /* XPMomentUserDataViewController.m in Sources */,
|
||||
@@ -12468,6 +12505,7 @@
|
||||
9B4D449328F15765002572D5 /* XPGiftLuckyGiftBroadcastView.m in Sources */,
|
||||
E81C278C26EAFAF60031E639 /* Base64.m in Sources */,
|
||||
238B37C92AC55A2C00BFC9D5 /* XPTreasureFairyStoreResultSmallView.m in Sources */,
|
||||
544B19B62CA14A7100885BEB /* CPGiftBanner.m in Sources */,
|
||||
E8C1CD7027D894B800376F83 /* RoomFaceTitleItemModel.m in Sources */,
|
||||
E85E7B4B2A4EB0D300B6D00A /* XPMineGuildManagerSetViewController.m in Sources */,
|
||||
189DD73D26E21C3F00AB55B1 /* YYUtility+Device.m in Sources */,
|
||||
|
21
YuMi/Assets.xcassets/1.0.16/cp_banner.imageset/Contents.json
vendored
Normal file
21
YuMi/Assets.xcassets/1.0.16/cp_banner.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "容器 8171@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.16/cp_banner.imageset/容器 8171@3x.png
vendored
Normal file
BIN
YuMi/Assets.xcassets/1.0.16/cp_banner.imageset/容器 8171@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 519 KiB |
BIN
YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_1.imageset/3@3x.png
vendored
Normal file
BIN
YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_1.imageset/3@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 39 KiB |
21
YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_1.imageset/Contents.json
vendored
Normal file
21
YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_1.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "3@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_2.imageset/3@3x-2.png
vendored
Normal file
BIN
YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_2.imageset/3@3x-2.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
21
YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_2.imageset/Contents.json
vendored
Normal file
21
YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_2.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "3@3x-2.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_3.imageset/3@3x-3.png
vendored
Normal file
BIN
YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_3.imageset/3@3x-3.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 39 KiB |
21
YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_3.imageset/Contents.json
vendored
Normal file
21
YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_3.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "3@3x-3.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_4.imageset/3@3x-4.png
vendored
Normal file
BIN
YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_4.imageset/3@3x-4.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
21
YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_4.imageset/Contents.json
vendored
Normal file
21
YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_4.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "3@3x-4.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_5.imageset/3@3x-5.png
vendored
Normal file
BIN
YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_5.imageset/3@3x-5.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
21
YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_5.imageset/Contents.json
vendored
Normal file
21
YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_5.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "3@3x-5.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
@@ -41,7 +41,7 @@
|
||||
|
||||
- (void)setModel:(RelationUserVO *)model {
|
||||
_model = model;
|
||||
[self.cpCard updateForCPList:model];
|
||||
[self.cpCard updateForCPList:model showBreakHeart:([AccountInfoStorage instance].getUid.integerValue == model.uid)];
|
||||
}
|
||||
|
||||
- (CPCard *)cpCard {
|
||||
|
@@ -219,7 +219,7 @@
|
||||
return kGetScaleWidth(116);
|
||||
}
|
||||
NSInteger lines = ceil((giftWall.count + luckyGiftWall.count)/4.0);
|
||||
return 42 + lines * (kGetScaleWidth(116) + 16);
|
||||
return lines * (kGetScaleWidth(107) + 16);
|
||||
}
|
||||
|
||||
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
|
||||
@@ -333,7 +333,7 @@
|
||||
}
|
||||
|
||||
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
return self.isMedal ? CGSizeMake(kGetScaleWidth(77), kGetScaleWidth(94)) : CGSizeMake(kGetScaleWidth(77), kGetScaleWidth(116));
|
||||
return self.isMedal ? CGSizeMake(kGetScaleWidth(77), kGetScaleWidth(94)) : CGSizeMake(kGetScaleWidth(77), kGetScaleWidth(107));
|
||||
}
|
||||
|
||||
|
||||
|
@@ -693,7 +693,7 @@ typedef enum : NSUInteger {
|
||||
[_tableView registerClass:[XPMineMultipleContentTableViewCell class] forCellReuseIdentifier:NSStringFromClass([XPMineMultipleContentTableViewCell class])];
|
||||
|
||||
UIView *footer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, kSafeAreaBottomHeight)];
|
||||
footer.backgroundColor = [UIColor purpleColor];
|
||||
footer.backgroundColor = [UIColor clearColor];
|
||||
_tableView.tableFooterView = footer;
|
||||
|
||||
if (isMSRTL()) {
|
||||
|
@@ -419,30 +419,18 @@ HWDMP4PlayDelegate>
|
||||
[self removeCPAnimation];
|
||||
}
|
||||
|
||||
//provide the content for tags, maybe text or url string ...
|
||||
//- (NSString *)contentForVapTag:(NSString *)tag resource:(QGVAPSourceInfo *)info {
|
||||
//
|
||||
// if ([tag isEqualToString:@"avatar1"]) {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// NSDictionary *extraInfo = @{@"[avatar1]" : self.userInfo.avatar,
|
||||
// @"[avatar2]" : @"https://www.popo8.com/gift/gift_231.png"};
|
||||
// return extraInfo[tag];
|
||||
//}
|
||||
|
||||
//provide image for url from tag content
|
||||
- (void)loadVapImageWithURL:(NSString *)urlStr context:(NSDictionary *)context completion:(VAPImageCompletionBlock)completionBlock {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
QGVAPSourceInfo *info = (QGVAPSourceInfo *)context[@"resource"];
|
||||
if ([info.contentTag isEqualToString:@"avatar1"] ) {
|
||||
self.avatarLoader = [[NetImageView alloc] init];
|
||||
[self.avatarLoader loadImageWithUrl:self.userInfo.avatar completion:^(UIImage * _Nullable image, NSURL * _Nonnull url) {
|
||||
[self.avatarLoader loadImageWithUrl:self.userInfo.relationUserVO.avatar completion:^(UIImage * _Nullable image, NSURL * _Nonnull url) {
|
||||
completionBlock(image, nil, urlStr);
|
||||
}];
|
||||
} else {
|
||||
self.cpAvatarLoader = [[NetImageView alloc] init];
|
||||
[self.cpAvatarLoader loadImageWithUrl:self.userInfo.avatar completion:^(UIImage * _Nullable image, NSURL * _Nonnull url) {
|
||||
[self.cpAvatarLoader loadImageWithUrl:self.userInfo.relationUserVO.cpAvatar completion:^(UIImage * _Nullable image, NSURL * _Nonnull url) {
|
||||
completionBlock(image, nil, urlStr);
|
||||
}];
|
||||
}
|
||||
|
24
YuMi/Modules/YMMine/View/SubViews/CPBindingAnimation.h
Normal file
24
YuMi/Modules/YMMine/View/SubViews/CPBindingAnimation.h
Normal file
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// CPBindingAnimation.h
|
||||
// YuMi
|
||||
//
|
||||
// Created by P on 2024/9/23.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@class AttachmentModel;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface CPBindingAnimation : UIView
|
||||
|
||||
@property (nonatomic, strong) AttachmentModel *cpAttachment;
|
||||
|
||||
+ (void)display:(UIView *)superView
|
||||
with:(AttachmentModel *)attachment
|
||||
complete:(void(^)(void))complete;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
139
YuMi/Modules/YMMine/View/SubViews/CPBindingAnimation.m
Normal file
139
YuMi/Modules/YMMine/View/SubViews/CPBindingAnimation.m
Normal file
@@ -0,0 +1,139 @@
|
||||
//
|
||||
// CPBindingAnimation.m
|
||||
// YuMi
|
||||
//
|
||||
// Created by P on 2024/9/23.
|
||||
//
|
||||
|
||||
#import "CPBindingAnimation.h"
|
||||
|
||||
#import "UIView+VAP.h"
|
||||
#import "AttachmentModel.h"
|
||||
#import "QGVAPConfigModel.h"
|
||||
|
||||
|
||||
@interface CPBindingAnimation() <HWDMP4PlayDelegate>
|
||||
|
||||
@property (nonatomic, strong) VAPView *cpVAPView;
|
||||
@property (nonatomic, strong) NetImageView *avatarLoader;
|
||||
@property (nonatomic, strong) NetImageView *cpAvatarLoader;
|
||||
|
||||
@property (nonatomic, copy) void(^completeDisplay)(void);
|
||||
|
||||
@end
|
||||
|
||||
@implementation CPBindingAnimation
|
||||
|
||||
- (instancetype)init {
|
||||
if (self = [super init]) {
|
||||
[self addSubview:self.cpVAPView];
|
||||
[self.cpVAPView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.edges.mas_equalTo(self);
|
||||
}];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
// {"data":{"giftUrl":"https://image.pekolive.com/I Do.png","partitionId":2,"receiverAvatar":"https://img.molistar.xyz/default_avatar_molistar.png","roomUid":3238,"senderAvatar":"https://img.molistar.xyz/default_avatar_molistar.png"},"first":64,"second":643}
|
||||
- (void)setCpAttachment:(AttachmentModel *)cpAttachment {
|
||||
_cpAttachment = cpAttachment;
|
||||
#if DEBUG
|
||||
if (cpAttachment == nil) {
|
||||
AttachmentModel *m = [[AttachmentModel alloc] init];
|
||||
m.data = @{@"senderAvatar":@"https://img.molistar.xyz/default_avatar_molistar.png", @"receiverAvatar":@"https://img.molistar.xyz/default_avatar_molistar.png"};
|
||||
_cpAttachment = m;
|
||||
}
|
||||
#endif
|
||||
[self startPlay];
|
||||
}
|
||||
|
||||
- (void)startPlay {
|
||||
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"CP绑定" ofType:@"mp4"];
|
||||
[self.cpVAPView playHWDMP4:filePath delegate:self];
|
||||
}
|
||||
|
||||
- (void)endPlay {
|
||||
if (_cpVAPView) {
|
||||
@kWeakify(self);
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (self.completeDisplay) {
|
||||
self.completeDisplay();
|
||||
}
|
||||
|
||||
@kStrongify(self);
|
||||
[self.cpVAPView removeFromSuperview];
|
||||
self.cpVAPView = nil;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)display:(UIView *)superView
|
||||
with:(AttachmentModel *)attachment
|
||||
complete:(void(^)(void))complete {
|
||||
CPBindingAnimation *cpBindingAnimation = [[CPBindingAnimation alloc] init];
|
||||
cpBindingAnimation.cpAttachment = attachment;
|
||||
cpBindingAnimation.completeDisplay = complete;
|
||||
[superView addSubview:cpBindingAnimation];
|
||||
[cpBindingAnimation mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.mas_equalTo(superView);
|
||||
make.top.mas_equalTo(146);
|
||||
make.width.mas_equalTo(KScreenWidth);
|
||||
make.height.mas_equalTo(kGetScaleWidth(272));
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - HWDMP4PlayDelegate
|
||||
- (NSString *)contentForVapTag:(NSString *)tag resource:(QGVAPSourceInfo *)info {
|
||||
NSDictionary *extraInfo = @{@"name1" : self.cpAttachment.data[@"senderNick"],
|
||||
@"name2" : self.cpAttachment.data[@"receiverNick"]};
|
||||
return extraInfo[tag];
|
||||
}
|
||||
|
||||
- (void)loadVapImageWithURL:(NSString *)urlStr
|
||||
context:(NSDictionary *)context
|
||||
completion:(VAPImageCompletionBlock)completionBlock {
|
||||
@kWeakify(self);
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
@kStrongify(self);
|
||||
QGVAPSourceInfo *info = (QGVAPSourceInfo *)context[@"resource"];
|
||||
if ([info.contentTag isEqualToString:@"avatar1"] ) {
|
||||
self.avatarLoader = [[NetImageView alloc] init];
|
||||
[self.avatarLoader loadImageWithUrl:self.cpAttachment.data[@"senderAvatar"] completion:^(UIImage * _Nullable image, NSURL * _Nonnull url) {
|
||||
completionBlock(image, nil, urlStr);
|
||||
}];
|
||||
} else {
|
||||
self.cpAvatarLoader = [[NetImageView alloc] init];
|
||||
[self.cpAvatarLoader loadImageWithUrl:self.cpAttachment.data[@"receiverAvatar"] completion:^(UIImage * _Nullable image, NSURL * _Nonnull url) {
|
||||
completionBlock(image, nil, urlStr);
|
||||
}];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (BOOL)shouldStartPlayMP4:(VAPView *)container config:(QGVAPConfigModel *)config {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)viewDidStopPlayMP4:(NSInteger)lastFrameIndex view:(VAPView *)container {
|
||||
[self endPlay];
|
||||
}
|
||||
|
||||
- (void)viewDidFinishPlayMP4:(NSInteger)totalFrameCount view:(VAPView *)container {
|
||||
[self endPlay];
|
||||
}
|
||||
|
||||
- (void)viewDidFailPlayMP4:(NSError *)error {
|
||||
[self endPlay];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
- (VAPView *)cpVAPView {
|
||||
if (!_cpVAPView) {
|
||||
_cpVAPView = [[VAPView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, 0)];
|
||||
_cpVAPView.contentMode = UIViewContentModeScaleAspectFill;
|
||||
}
|
||||
return _cpVAPView;
|
||||
}
|
||||
|
||||
|
||||
@end
|
@@ -16,7 +16,7 @@
|
||||
@property (nonatomic, copy) void(^breakTheHeart)(RelationUserVO *model);
|
||||
|
||||
- (void)updateForUserPage:(RelationUserVO *)model;
|
||||
- (void)updateForCPList:(RelationUserVO *)model;
|
||||
- (void)updateForCPList:(RelationUserVO *)model showBreakHeart:(BOOL)showBreakHeart;
|
||||
|
||||
|
||||
@end
|
||||
|
@@ -189,9 +189,11 @@
|
||||
self.breakYourHeartButton.hidden = YES;
|
||||
}
|
||||
|
||||
- (void)updateForCPList:(RelationUserVO *)model {
|
||||
- (void)updateForCPList:(RelationUserVO *)model showBreakHeart:(BOOL)showBreakHeart {
|
||||
self.relationUser = model;
|
||||
|
||||
self.breakYourHeartButton.hidden = !showBreakHeart;
|
||||
|
||||
[self.backgroundImage mas_updateConstraints:^(MASConstraintMaker *make) {
|
||||
make.bottom.mas_equalTo(self).offset(-12);
|
||||
}];
|
||||
|
24
YuMi/Modules/YMMine/View/SubViews/CPGiftBanner.h
Normal file
24
YuMi/Modules/YMMine/View/SubViews/CPGiftBanner.h
Normal file
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// CPGiftBanner.h
|
||||
// YuMi
|
||||
//
|
||||
// Created by P on 2024/9/23.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@class AttachmentModel;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface CPGiftBanner : UIView
|
||||
|
||||
@property (nonatomic, strong) AttachmentModel *bannerAttachment;
|
||||
|
||||
+ (void)display:(UIView *)superView
|
||||
with:(AttachmentModel *)attachment
|
||||
complete:(void(^)(void))complete;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
165
YuMi/Modules/YMMine/View/SubViews/CPGiftBanner.m
Normal file
165
YuMi/Modules/YMMine/View/SubViews/CPGiftBanner.m
Normal file
@@ -0,0 +1,165 @@
|
||||
//
|
||||
// CPGiftBanner.m
|
||||
// YuMi
|
||||
//
|
||||
// Created by P on 2024/9/23.
|
||||
//
|
||||
|
||||
#import "CPGiftBanner.h"
|
||||
|
||||
#import "AttachmentModel.h"
|
||||
|
||||
@interface CPGiftBanner()
|
||||
|
||||
@property (nonatomic, strong) NetImageView *avatar_sender;
|
||||
@property (nonatomic, strong) NetImageView *avatar_receiver;
|
||||
@property (nonatomic, strong) NetImageView *giftImageView;
|
||||
|
||||
@property (nonatomic, copy) void(^completeDisplay)(void);
|
||||
|
||||
@end
|
||||
|
||||
@implementation CPGiftBanner
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
if (self = [super initWithFrame:frame]) {
|
||||
UIImageView *background = [self backgroundImageView];
|
||||
[self addSubview:background];
|
||||
[background mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.edges.mas_equalTo(self);
|
||||
}];
|
||||
|
||||
UIStackView *stack = [[UIStackView alloc] init];
|
||||
stack.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
stack.spacing = 8;
|
||||
stack.distribution = UIStackViewDistributionEqualSpacing;
|
||||
stack.alignment = UIStackViewAlignmentCenter;
|
||||
[self addSubview:stack];
|
||||
[stack mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.mas_equalTo(self);
|
||||
make.height.mas_equalTo(50);
|
||||
make.bottom.mas_equalTo(self).offset(-40);
|
||||
}];
|
||||
|
||||
UILabel *label_1 = [self labelWith:@"Send"];
|
||||
UILabel *label_2 = [self labelWith:@"CP Gift"];
|
||||
[stack addArrangedSubview:self.avatar_sender];
|
||||
[stack addArrangedSubview:label_1];
|
||||
[stack addArrangedSubview:self.avatar_receiver];
|
||||
[stack addArrangedSubview:label_2];
|
||||
[stack addArrangedSubview:self.giftImageView];
|
||||
|
||||
[self.avatar_sender mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.width.height.mas_equalTo(38);
|
||||
}];
|
||||
|
||||
[label_1 mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.width.mas_greaterThanOrEqualTo(32);
|
||||
make.height.mas_equalTo(20);
|
||||
}];
|
||||
|
||||
[self.avatar_receiver mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.width.height.mas_equalTo(38);
|
||||
}];
|
||||
|
||||
[label_2 mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.width.mas_greaterThanOrEqualTo(46);
|
||||
make.height.mas_equalTo(20);
|
||||
}];
|
||||
|
||||
[self.giftImageView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.width.height.mas_equalTo(50);
|
||||
}];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setBannerAttachment:(AttachmentModel *)bannerAttachment {
|
||||
_bannerAttachment = bannerAttachment;
|
||||
self.avatar_sender.imageUrl = bannerAttachment.data[@"senderAvatar"];
|
||||
self.avatar_receiver.imageUrl = bannerAttachment.data[@"receiverAvatar"];
|
||||
self.giftImageView.imageUrl = bannerAttachment.data[@"giftUrl"];
|
||||
}
|
||||
|
||||
+ (void)display:(UIView *)superView
|
||||
with:(AttachmentModel *)attachment
|
||||
complete:(void(^)(void))complete {
|
||||
|
||||
CGFloat width = KScreenWidth;
|
||||
CGFloat height = kGetScaleWidth(145);
|
||||
CPGiftBanner *bannerView = [[CPGiftBanner alloc] initWithFrame:CGRectMake(KScreenWidth, 50, width, height)];
|
||||
bannerView.bannerAttachment = attachment;
|
||||
bannerView.completeDisplay = complete;
|
||||
[superView addSubview:bannerView];
|
||||
|
||||
@kWeakify(bannerView);
|
||||
[UIView animateWithDuration:0.25 animations:^{
|
||||
bannerView.center = CGPointMake(superView.center.x, height/2 + 50);
|
||||
} completion:^(BOOL finished) {
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
|
||||
bannerView.frame = CGRectMake(-KScreenWidth, 50, width, height);
|
||||
} completion:^(BOOL finished) {
|
||||
@kStrongify(bannerView);
|
||||
if (bannerView.completeDisplay) {
|
||||
bannerView.completeDisplay();
|
||||
}
|
||||
[bannerView removeFromSuperview];
|
||||
}];
|
||||
});
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
- (UIImageView *)backgroundImageView {
|
||||
UIImageView *iv = [[UIImageView alloc] init];
|
||||
iv.contentMode = UIViewContentModeScaleAspectFit;
|
||||
iv.image = kImage(@"cp_banner");
|
||||
return iv;
|
||||
}
|
||||
|
||||
-(UILabel *)labelWith:(NSString *)content {
|
||||
return [UILabel labelInitWithText:content
|
||||
font:kFontSemibold(13)
|
||||
textColor:UIColorFromRGB(0xFFE6A0)];
|
||||
}
|
||||
|
||||
- (NetImageConfig *)avatarConfig {
|
||||
NetImageConfig * config = [[NetImageConfig alloc]init];
|
||||
config.imageType = ImageTypeUserIcon;
|
||||
config.placeHolder = [UIImageConstant defaultAvatarPlaceholder];
|
||||
return config;
|
||||
}
|
||||
|
||||
- (NetImageView *)avatar_sender {
|
||||
if (!_avatar_sender) {
|
||||
_avatar_sender = [[NetImageView alloc] initWithConfig:[self avatarConfig]];
|
||||
_avatar_sender.layer.masksToBounds = YES;
|
||||
_avatar_sender.layer.cornerRadius = 38/2;
|
||||
_avatar_sender.layer.borderColor = [UIColor whiteColor].CGColor;
|
||||
_avatar_sender.layer.borderWidth = 1;
|
||||
}
|
||||
return _avatar_sender;
|
||||
}
|
||||
|
||||
- (NetImageView *)avatar_receiver {
|
||||
if (!_avatar_receiver) {
|
||||
_avatar_receiver = [[NetImageView alloc] initWithConfig:[self avatarConfig]];
|
||||
_avatar_receiver.layer.masksToBounds = YES;
|
||||
_avatar_receiver.layer.cornerRadius = 38/2;
|
||||
_avatar_receiver.layer.borderColor = [UIColor whiteColor].CGColor;
|
||||
_avatar_receiver.layer.borderWidth = 1;
|
||||
}
|
||||
return _avatar_receiver;
|
||||
}
|
||||
|
||||
- (NetImageView *)giftImageView {
|
||||
if (!_giftImageView) {
|
||||
_giftImageView = [[NetImageView alloc] initWithConfig:[self avatarConfig]];
|
||||
_giftImageView.layer.masksToBounds = YES;
|
||||
_giftImageView.layer.cornerRadius = 50/2;
|
||||
}
|
||||
return _giftImageView;
|
||||
}
|
||||
|
||||
@end
|
24
YuMi/Modules/YMMine/View/SubViews/CPLevelUpAnimation.h
Normal file
24
YuMi/Modules/YMMine/View/SubViews/CPLevelUpAnimation.h
Normal file
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// CPLevelUpAnimation.h
|
||||
// YuMi
|
||||
//
|
||||
// Created by P on 2024/9/23.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@class AttachmentModel;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface CPLevelUpAnimation : UIView
|
||||
|
||||
@property (nonatomic, strong) AttachmentModel *cpAttachment;
|
||||
|
||||
+ (void)display:(UIView *)superView
|
||||
with:(AttachmentModel *)attachment
|
||||
complete:(void(^)(void))complete;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
193
YuMi/Modules/YMMine/View/SubViews/CPLevelUpAnimation.m
Normal file
193
YuMi/Modules/YMMine/View/SubViews/CPLevelUpAnimation.m
Normal file
@@ -0,0 +1,193 @@
|
||||
//
|
||||
// CPLevelUpAnimation.m
|
||||
// YuMi
|
||||
//
|
||||
// Created by P on 2024/9/23.
|
||||
//
|
||||
|
||||
#import "CPLevelUpAnimation.h"
|
||||
|
||||
#import "SVGA.h"
|
||||
#import "AttachmentModel.h"
|
||||
|
||||
@interface CPLevelUpAnimation()
|
||||
|
||||
@property (nonatomic, strong) SVGAImageView *backgroundSvga;
|
||||
@property (nonatomic, strong) UIImageView *bottomBannerImageView;
|
||||
@property (nonatomic, strong) UILabel *bottomContentLabel;
|
||||
|
||||
@property (nonatomic, copy) void(^completeDisplay)(void);
|
||||
|
||||
@property (nonatomic, strong) NSTimer *endPlayTimer;
|
||||
|
||||
@end
|
||||
|
||||
@implementation CPLevelUpAnimation
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
if (self = [super initWithFrame:frame]) {
|
||||
[self addSubview:self.backgroundSvga];
|
||||
[self.backgroundSvga mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.edges.mas_equalTo(self);
|
||||
}];
|
||||
|
||||
[self addSubview:self.bottomBannerImageView];
|
||||
[self.bottomBannerImageView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.bottom.mas_equalTo(self).offset(-19);
|
||||
make.centerX.mas_equalTo(self);
|
||||
make.height.mas_equalTo(17);
|
||||
make.width.mas_equalTo(kGetScaleWidth(291));
|
||||
}];
|
||||
|
||||
[self addSubview:self.bottomContentLabel];
|
||||
[self.bottomContentLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.center.mas_equalTo(self.bottomBannerImageView);
|
||||
}];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setCpAttachment:(AttachmentModel *)cpAttachment {
|
||||
|
||||
|
||||
// {
|
||||
// cpLevel = 1;
|
||||
// partitionId = 4;
|
||||
// receiverAvatar = "https://img.molistar.xyz/default_avatar_molistar.png";
|
||||
// receiverNick = "\U7231\U5764\Ud83d\Udc14";
|
||||
// receiverUid = 3164;
|
||||
// roomUid = 3133;
|
||||
// senderAvatar = "https://image.pekolive.com/image/3283950eebfb7a55ab84e5b15cc29421.jpeg";
|
||||
// senderNick = "\U5468\U59d0\U4f26";
|
||||
// senderUid = 3133;
|
||||
// }
|
||||
|
||||
_cpAttachment = cpAttachment;
|
||||
|
||||
NSNumber *level = cpAttachment.data[@"cpLevel"];
|
||||
NSString *bannerImageName = [NSString stringWithFormat:@"cp_level_banner_lv_%@", level];
|
||||
self.bottomBannerImageView.image = kImage(bannerImageName);
|
||||
|
||||
NSString *senderName = cpAttachment.data[@"senderNick"];
|
||||
NSString *receiverName = cpAttachment.data[@"receiverNick"];
|
||||
[self updateLabelContent:senderName and:receiverName level:level.integerValue];
|
||||
|
||||
@kWeakify(self);
|
||||
SVGAParser *parser = [SVGAParser new];
|
||||
[parser parseWithNamed:[NSString stringWithFormat:@"level up %@", level]
|
||||
inBundle:[NSBundle mainBundle]
|
||||
completionBlock:^(SVGAVideoEntity * _Nonnull videoItem) {
|
||||
@kStrongify(self);
|
||||
NSString *senderAvatar = cpAttachment.data[@"senderAvatar"];
|
||||
NSString *receiverAvatar = cpAttachment.data[@"receiverAvatar"];
|
||||
self.backgroundSvga.videoItem = videoItem;
|
||||
[self.backgroundSvga setImageWithURL:[NSURL URLWithString:senderAvatar] forKey:@"user_img1"];
|
||||
[self.backgroundSvga setImageWithURL:[NSURL URLWithString:receiverAvatar] forKey:@"user_img2"];
|
||||
[self.backgroundSvga startAnimation];
|
||||
[self startTimer];
|
||||
} failureBlock:^(NSError * _Nonnull error) {
|
||||
@kStrongify(self);
|
||||
[self removeFromSuperview];
|
||||
if (self.completeDisplay) {
|
||||
self.completeDisplay();
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)updateLabelContent:(NSString *)name_1 and:(NSString *)name_2 level:(NSInteger)level {
|
||||
// 根据 level 确定 relation ship
|
||||
NSString *relationship = @"";
|
||||
switch (level) {
|
||||
case 1:
|
||||
relationship = @"Dup CP";
|
||||
break;
|
||||
case 2:
|
||||
relationship = @"Best Friends";
|
||||
break;
|
||||
case 3:
|
||||
relationship = @"Soulmates";
|
||||
break;
|
||||
case 4:
|
||||
relationship = @"Soulmates";
|
||||
break;
|
||||
case 5:
|
||||
relationship = @"Soulmates";
|
||||
break;
|
||||
default:
|
||||
relationship = @"Moli Star";
|
||||
break;
|
||||
}
|
||||
|
||||
// 构造文本内容
|
||||
NSString *fullText = [NSString stringWithFormat:@"%@ and %@ Become %@", name_1, name_2, relationship];
|
||||
|
||||
// 创建可变的 attributed string
|
||||
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:fullText];
|
||||
|
||||
// 设置默认颜色为白色
|
||||
[attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:NSMakeRange(0, fullText.length)];
|
||||
|
||||
// 找到 "and" 的位置,并设置其颜色为黄色
|
||||
NSRange andRange = [fullText rangeOfString:@"and"];
|
||||
if (andRange.location != NSNotFound) {
|
||||
[attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor yellowColor] range:andRange];
|
||||
}
|
||||
|
||||
// 找到 "Become" 的位置,并设置其颜色为黄色
|
||||
NSRange becomeRange = [fullText rangeOfString:@"Become"];
|
||||
if (becomeRange.location != NSNotFound) {
|
||||
[attributedString addAttribute:NSForegroundColorAttributeName value:UIColorFromRGB(0xFFF664) range:becomeRange];
|
||||
}
|
||||
|
||||
// 将生成的 attributed string 赋值给 UILabel
|
||||
self.bottomContentLabel.attributedText = attributedString;
|
||||
}
|
||||
|
||||
+ (void)display:(UIView *)superView
|
||||
with:(AttachmentModel *)attachment
|
||||
complete:(void (^)(void))complete {
|
||||
CPLevelUpAnimation *levelUp = [[CPLevelUpAnimation alloc] initWithFrame:CGRectMake(0, 190, KScreenWidth, kGetScaleWidth(145))];
|
||||
levelUp.cpAttachment = attachment;
|
||||
levelUp.completeDisplay = complete;
|
||||
[superView addSubview:levelUp];
|
||||
}
|
||||
|
||||
- (void)startTimer {
|
||||
@kWeakify(self);
|
||||
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:3 repeats:NO block:^(NSTimer * _Nonnull timer) {
|
||||
@kStrongify(self);
|
||||
[self removeFromSuperview];
|
||||
[self.backgroundSvga stopAnimation];
|
||||
if (self.completeDisplay) {
|
||||
self.completeDisplay();
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
- (SVGAImageView *)backgroundSvga {
|
||||
if (!_backgroundSvga) {
|
||||
_backgroundSvga = [[SVGAImageView alloc]init];
|
||||
_backgroundSvga.backgroundColor = [UIColor clearColor];
|
||||
_backgroundSvga.autoPlay = YES;
|
||||
}
|
||||
return _backgroundSvga;
|
||||
}
|
||||
|
||||
- (UIImageView *)bottomBannerImageView {
|
||||
if (!_bottomBannerImageView) {
|
||||
_bottomBannerImageView = [[UIImageView alloc] initWithImage:kImage(@"cp_level_banner_lv_1")];
|
||||
}
|
||||
return _bottomBannerImageView;
|
||||
}
|
||||
|
||||
- (UILabel *)bottomContentLabel {
|
||||
if (!_bottomContentLabel) {
|
||||
_bottomContentLabel = [UILabel labelInitWithText:@"" font:kFontMedium(12) textColor:[UIColor whiteColor]];
|
||||
_bottomContentLabel.textAlignment = NSTextAlignmentCenter;
|
||||
}
|
||||
return _bottomContentLabel;
|
||||
}
|
||||
|
||||
|
||||
@end
|
@@ -208,7 +208,7 @@ return view;\
|
||||
|
||||
// 创建一个新的视图作为蒙层
|
||||
UIView *overlay = [[UIView alloc] initWithFrame:self.pi_cycleScrollView.bounds];
|
||||
|
||||
overlay.userInteractionEnabled = NO;
|
||||
// 设置蒙层背景色为黑色,透明度为 0.5
|
||||
overlay.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
|
||||
|
||||
@@ -940,7 +940,7 @@ return view;\
|
||||
placeholderImage:[UIImageConstant defaultBannerPlaceholder]];
|
||||
_pi_cycleScrollView.backgroundColor = [UIColor clearColor];
|
||||
_pi_cycleScrollView.bannerImageViewContentMode = UIViewContentModeScaleAspectFill;
|
||||
_pi_cycleScrollView.pageControlStyle = SDCycleScrollViewPageContolStyleAnimated;//SDCycleScrollViewPageContolStyleNone;
|
||||
_pi_cycleScrollView.pageControlStyle = SDCycleScrollViewPageContolStyleNone;
|
||||
_pi_cycleScrollView.autoScroll = NO;
|
||||
// SDCycleScrollView没有适配阿语,在RTL下会乱滚,都用LTR算了
|
||||
_pi_cycleScrollView.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight;
|
||||
|
@@ -71,6 +71,10 @@
|
||||
|
||||
#import "LuckyGiftWinningBannerView.h"
|
||||
|
||||
#import "CPGiftBanner.h"
|
||||
#import "CPLevelUpAnimation.h"
|
||||
#import "CPBindingAnimation.h"
|
||||
|
||||
@interface XPRoomAnimationView ()<
|
||||
SVGAPlayerDelegate,
|
||||
NIMBroadcastManagerDelegate,
|
||||
@@ -170,13 +174,11 @@ HWDMP4PlayDelegate>
|
||||
|
||||
@property (nonatomic, copy) NSString *GiftDynamicEffectListPath;
|
||||
|
||||
@property (nonatomic, strong) NSMutableArray *roomLuckWinningBannerModels;
|
||||
@property (nonatomic, assign) BOOL isDisplayLuckWinningBanner;
|
||||
/// 新的特效播放队列,包括幸运礼物 banner, CP banner 和 CP 特效
|
||||
@property (nonatomic, strong) NSMutableArray *roomEffectModelsQueueV2;
|
||||
@property (nonatomic, assign) BOOL isRoomEffectV2Displaying;
|
||||
|
||||
///CP特效
|
||||
@property (nonatomic, strong) VAPView *cpVAPView;
|
||||
@property (nonatomic, strong) NetImageView *avatarLoader;
|
||||
@property (nonatomic, strong) NetImageView *cpAvatarLoader;
|
||||
@property (nonatomic, strong) AttachmentModel *cpAttachment;
|
||||
|
||||
@end
|
||||
@@ -208,7 +210,7 @@ HWDMP4PlayDelegate>
|
||||
[self initSubViews];
|
||||
[self initSubViewConstraints];
|
||||
|
||||
_roomLuckWinningBannerModels = [NSMutableArray array];
|
||||
_roomEffectModelsQueueV2 = [NSMutableArray array];
|
||||
_GiftDynamicEffectListPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) xpSafeObjectAtIndex:0] stringByAppendingPathComponent:@"GiftDynamicEffectList"];
|
||||
|
||||
}
|
||||
@@ -387,15 +389,7 @@ HWDMP4PlayDelegate>
|
||||
attachment.second == Custom_Message_Sub_Super_Gift_Winning_Coins_ALL_Room) {
|
||||
[self receiveLuckGiftBanner:attachment];
|
||||
} else if (attachment.first == CustomMessageType_CP) {
|
||||
self.cpAttachment = attachment;
|
||||
if (attachment.second == Custom_Message_Sub_CP_Gift) {
|
||||
|
||||
} else if (attachment.second == Custom_Message_Sub_CP_Upgrade) {
|
||||
|
||||
} else if (attachment.second == Custom_Message_Sub_CP_Binding) {
|
||||
[self playCPBinding];
|
||||
// {"data":{"giftUrl":"https://image.pekolive.com/I Do.png","partitionId":2,"receiverAvatar":"https://img.molistar.xyz/default_avatar_molistar.png","roomUid":3238,"senderAvatar":"https://img.molistar.xyz/default_avatar_molistar.png"},"first":64,"second":643}
|
||||
}
|
||||
[self receiveCPEvent: attachment];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -429,33 +423,56 @@ HWDMP4PlayDelegate>
|
||||
}
|
||||
|
||||
- (void)receiveLuckGiftBanner:(AttachmentModel *)attachment {
|
||||
[self.roomLuckWinningBannerModels addObject:attachment];
|
||||
if (!self.isDisplayLuckWinningBanner) {
|
||||
[self processNextLuckWinningAttachment];
|
||||
[self.roomEffectModelsQueueV2 addObject:attachment];
|
||||
if (!self.isRoomEffectV2Displaying) {
|
||||
[self processNextRoomEffectAttachment];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)processNextLuckWinningAttachment {
|
||||
- (void)processNextRoomEffectAttachment {
|
||||
// 检查队列是否有元素
|
||||
if (self.roomLuckWinningBannerModels.count == 0) {
|
||||
if (self.roomEffectModelsQueueV2.count == 0) {
|
||||
// 如果队列为空,停止处理
|
||||
self.isDisplayLuckWinningBanner = NO;
|
||||
self.isRoomEffectV2Displaying = NO;
|
||||
return;
|
||||
}
|
||||
|
||||
// 从队列中取出第一个元素并移出队列
|
||||
AttachmentModel *nextAttachment = [self.roomLuckWinningBannerModels firstObject];
|
||||
[self.roomLuckWinningBannerModels removeObjectAtIndex:0];
|
||||
AttachmentModel *nextAttachment = [self.roomEffectModelsQueueV2 firstObject];
|
||||
[self.roomEffectModelsQueueV2 removeObjectAtIndex:0];
|
||||
|
||||
// 设置为正在显示的状态
|
||||
self.isDisplayLuckWinningBanner = YES;
|
||||
self.isRoomEffectV2Displaying = YES;
|
||||
|
||||
switch (nextAttachment.second) {
|
||||
case Custom_Message_Sub_Super_Gift_Winning_Coins_ALL_Room:
|
||||
[self playLuckyWinningBanner:nextAttachment];
|
||||
break;
|
||||
case Custom_Message_Sub_CP_Gift:
|
||||
[self playCPGiftBanner:nextAttachment];
|
||||
break;
|
||||
case Custom_Message_Sub_CP_Upgrade:
|
||||
[self playCPLevelUp:nextAttachment];
|
||||
break;
|
||||
case Custom_Message_Sub_CP_Binding:
|
||||
[self playCPBinding:nextAttachment];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)playLuckyWinningBanner:(AttachmentModel *)nextAttachment {
|
||||
RoomInfoModel *roomInfo = self.delegate.getRoomInfo;
|
||||
// 执行 display 方法
|
||||
@kWeakify(self);
|
||||
[LuckyGiftWinningBannerView display:self inRoomUid:roomInfo.uid with:nextAttachment complete:^{
|
||||
[LuckyGiftWinningBannerView display:self
|
||||
inRoomUid:roomInfo.uid
|
||||
with:nextAttachment
|
||||
complete:^{
|
||||
@kStrongify(self);
|
||||
// Display 完成后,继续处理下一个
|
||||
[self processNextLuckWinningAttachment];
|
||||
[self processNextRoomEffectAttachment];
|
||||
} exitCurrentRoom:^{
|
||||
@kStrongify(self);
|
||||
[self.delegate exitRoom];
|
||||
@@ -2526,42 +2543,41 @@ HWDMP4PlayDelegate>
|
||||
}
|
||||
|
||||
#pragma mark - CP 礼物
|
||||
- (void)playCPBinding {
|
||||
[self addSubview:self.cpVAPView];
|
||||
[self.cpVAPView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.mas_equalTo(self);
|
||||
make.top.mas_equalTo(146);
|
||||
make.width.mas_equalTo(KScreenWidth);
|
||||
make.height.mas_equalTo(230);
|
||||
- (void)receiveCPEvent:(AttachmentModel *)attachment {
|
||||
[self.roomEffectModelsQueueV2 addObject:attachment];
|
||||
if (!self.isRoomEffectV2Displaying) {
|
||||
[self processNextRoomEffectAttachment];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)playCPBinding:(AttachmentModel *)attachment {
|
||||
@kWeakify(self);
|
||||
[CPBindingAnimation display:self
|
||||
with:attachment
|
||||
complete:^{
|
||||
@kStrongify(self);
|
||||
[self processNextRoomEffectAttachment];
|
||||
}];
|
||||
|
||||
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"CP绑定" ofType:@"mp4"];
|
||||
[self.cpVAPView playHWDMP4:filePath delegate:self];
|
||||
}
|
||||
|
||||
//provide the content for tags, maybe text or url string ...
|
||||
- (NSString *)contentForVapTag:(NSString *)tag resource:(QGVAPSourceInfo *)info {
|
||||
NSDictionary *extraInfo = @{@"[name1]" : @"你阿妈",//self.cpAttachment.data[@"你阿妈"],
|
||||
@"[name2]" : @"你阿爸"};
|
||||
return extraInfo[tag];
|
||||
- (void)playCPGiftBanner:(AttachmentModel *)attachMent {
|
||||
@kWeakify(self);
|
||||
[CPGiftBanner display:self
|
||||
with:attachMent
|
||||
complete:^{
|
||||
@kStrongify(self);
|
||||
[self processNextRoomEffectAttachment];
|
||||
}];
|
||||
}
|
||||
|
||||
//provide image for url from tag content
|
||||
- (void)loadVapImageWithURL:(NSString *)urlStr context:(NSDictionary *)context completion:(VAPImageCompletionBlock)completionBlock {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
QGVAPSourceInfo *info = (QGVAPSourceInfo *)context[@"resource"];
|
||||
if ([info.contentTag isEqualToString:@"avatar1"] ) {
|
||||
self.avatarLoader = [[NetImageView alloc] init];
|
||||
[self.avatarLoader loadImageWithUrl:self.cpAttachment.data[@"senderAvatar"] completion:^(UIImage * _Nullable image, NSURL * _Nonnull url) {
|
||||
completionBlock(image, nil, urlStr);
|
||||
}];
|
||||
} else {
|
||||
self.cpAvatarLoader = [[NetImageView alloc] init];
|
||||
[self.cpAvatarLoader loadImageWithUrl:self.cpAttachment.data[@"receiverAvatar"] completion:^(UIImage * _Nullable image, NSURL * _Nonnull url) {
|
||||
completionBlock(image, nil, urlStr);
|
||||
}];
|
||||
}
|
||||
});
|
||||
- (void)playCPLevelUp:(AttachmentModel *)attachMent {
|
||||
@kWeakify(self);
|
||||
[CPLevelUpAnimation display:self
|
||||
with:attachMent
|
||||
complete:^{
|
||||
@kStrongify(self);
|
||||
[self processNextRoomEffectAttachment];
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - 心愿礼物
|
||||
@@ -2599,10 +2615,6 @@ HWDMP4PlayDelegate>
|
||||
#pragma mark - HWDMP4PlayDelegate
|
||||
//即将开始播放时询问,true马上开始播放,false放弃播放
|
||||
- (BOOL)shouldStartPlayMP4:(VAPView *)container config:(QGVAPConfigModel *)config {
|
||||
if (container == self.cpVAPView) {
|
||||
return YES;
|
||||
}
|
||||
|
||||
CGFloat width = config.info.size.width;
|
||||
CGFloat height = config.info.size.height;
|
||||
|
||||
@@ -2635,9 +2647,6 @@ HWDMP4PlayDelegate>
|
||||
} else if(container == self.luckyVapGiftEffectView) {
|
||||
[self.luckyVapGiftEffectView removeFromSuperview];
|
||||
self.luckyVapGiftEffectView = nil;
|
||||
} else if (container == self.cpVAPView) {
|
||||
[self.cpVAPView removeFromSuperview];
|
||||
self.cpVAPView = nil;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -2674,11 +2683,6 @@ HWDMP4PlayDelegate>
|
||||
if (self.isLargeGiftAnimating == YES) {
|
||||
self.isLargeGiftAnimating = NO;
|
||||
}
|
||||
|
||||
if (_cpVAPView) {
|
||||
[self.cpVAPView removeFromSuperview];
|
||||
self.cpVAPView = nil;
|
||||
}
|
||||
}
|
||||
#pragma mark - PAGViewListener
|
||||
/**
|
||||
@@ -3014,13 +3018,4 @@ HWDMP4PlayDelegate>
|
||||
return _broadCastHieght;
|
||||
}
|
||||
|
||||
- (VAPView *)cpVAPView {
|
||||
if (!_cpVAPView) {
|
||||
_cpVAPView = [[VAPView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)];
|
||||
_cpVAPView.contentMode = UIViewContentModeScaleAspectFill;
|
||||
_cpVAPView.hwd_Delegate = self;
|
||||
}
|
||||
return _cpVAPView;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@@ -38,8 +38,6 @@
|
||||
|
||||
@interface XPRoomMenuContainerView ()<XPRoomMessageBubbleViewDelegate>
|
||||
|
||||
///
|
||||
//@property (nonatomic,strong) UIStackView *stackView;
|
||||
///输入框
|
||||
@property (nonatomic,strong) UIButton *inputButton;
|
||||
///麦
|
||||
@@ -69,6 +67,9 @@
|
||||
@property (nonatomic,strong) XPRoomMessageBubbleView *miniMessageView;
|
||||
///代理
|
||||
@property (nonatomic,weak) id<RoomHostDelegate> delegate;
|
||||
|
||||
@property (nonatomic, strong) UIStackView *stackView;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -235,29 +236,24 @@
|
||||
|
||||
#pragma mark - Private Method
|
||||
- (void)initSubViews {
|
||||
// self.backgroundColor = UIColorRGBAlpha(0xFFFFFF, 0.2);
|
||||
|
||||
UIStackView *stack = [[UIStackView alloc] init];
|
||||
stack.spacing = 9;
|
||||
stack.alignment = UIStackViewAlignmentBottom;
|
||||
// stack.backgroundColor = [UIColor systemPurpleColor];
|
||||
[self addSubview:stack];
|
||||
[stack mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
[self addSubview:self.stackView];
|
||||
[self.stackView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.mas_equalTo(self);
|
||||
make.leading.mas_equalTo(self).offset(15);
|
||||
make.trailing.mas_equalTo(self).offset(-15);
|
||||
make.height.mas_equalTo(46);
|
||||
}];
|
||||
|
||||
[stack addArrangedSubview:self.inputButton];
|
||||
[stack addArrangedSubview:self.micButton];
|
||||
[stack addArrangedSubview:self.voiceButton];
|
||||
[stack addArrangedSubview:self.arrangeMicButton];
|
||||
[stack addArrangedSubview:self.messageButton];
|
||||
[stack addArrangedSubview:self.moreButton];
|
||||
[stack addArrangedSubview:self.svgDisplayView];
|
||||
|
||||
[stack addSubview:self.faceButton];
|
||||
[stack addSubview:self.giftButton];
|
||||
[self.stackView addArrangedSubview:self.inputButton];
|
||||
[self.stackView addArrangedSubview:self.micButton];
|
||||
[self.stackView addArrangedSubview:self.voiceButton];
|
||||
[self.stackView addArrangedSubview:self.arrangeMicButton];
|
||||
[self.stackView addArrangedSubview:self.messageButton];
|
||||
[self.stackView addArrangedSubview:self.moreButton];
|
||||
[self.stackView addArrangedSubview:self.svgDisplayView];
|
||||
|
||||
[self.stackView addSubview:self.faceButton];
|
||||
[self.stackView addSubview:self.giftButton];
|
||||
|
||||
@kWeakify(self);
|
||||
[self.parser parseWithNamed:@"ms_room_gift_svga_icon" inBundle:nil completionBlock:^(SVGAVideoEntity * _Nonnull videoItem) {
|
||||
@@ -268,37 +264,9 @@
|
||||
[self.svgDisplayView startAnimation];
|
||||
} failureBlock:^(NSError * _Nullable error) {
|
||||
}];
|
||||
|
||||
return;
|
||||
|
||||
// [self.stackView addArrangedSubview:self.micButton];
|
||||
// [self.stackView addArrangedSubview:self.voiceButton];
|
||||
// [self.stackView addArrangedSubview:self.faceButton];
|
||||
// [self.stackView addArrangedSubview:self.arrangeMicButton];
|
||||
// [self.stackView addArrangedSubview:self.messageButton];
|
||||
// [self.stackView addArrangedSubview:self.moreButton];
|
||||
// [self.stackView addArrangedSubview:self.baiShunGameButton];
|
||||
// [self.stackView addArrangedSubview:self.pkButton];
|
||||
|
||||
|
||||
// if (isMSRTL()) {
|
||||
// self.stackView.transform = CGAffineTransformMakeRotation(M_PI);
|
||||
// }else{
|
||||
// self.stackView.transform = CGAffineTransformIdentity;
|
||||
// }
|
||||
}
|
||||
|
||||
- (void)initSubViewConstraints {
|
||||
// [self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
// make.top.mas_equalTo(self).offset(16);
|
||||
// make.height.mas_equalTo(29);
|
||||
// make.leading.mas_equalTo(self.inputButton.mas_trailing).offset(15);
|
||||
// make.trailing.mas_equalTo(self.giftButton.mas_leading).offset(-11);
|
||||
// }];
|
||||
//
|
||||
// [self.stackView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
// make.top.bottom.leading.trailing.height.mas_equalTo(self.scrollView);
|
||||
// }];
|
||||
|
||||
[self.inputButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
// make.top.mas_equalTo(16);
|
||||
@@ -678,16 +646,15 @@
|
||||
}
|
||||
return _parser;
|
||||
}
|
||||
//- (UIStackView *)stackView {
|
||||
// if (!_stackView) {
|
||||
// _stackView = [[UIStackView alloc] init];
|
||||
// _stackView.axis = UILayoutConstraintAxisHorizontal;
|
||||
// _stackView.distribution = UIStackViewDistributionFill;
|
||||
// _stackView.alignment = UIStackViewAlignmentLeading;
|
||||
// _stackView.spacing = 11;
|
||||
// }
|
||||
// return _stackView;
|
||||
//}
|
||||
|
||||
- (UIStackView *)stackView {
|
||||
if (!_stackView) {
|
||||
_stackView = [[UIStackView alloc] init];
|
||||
_stackView.spacing = 9;
|
||||
_stackView.alignment = UIStackViewAlignmentBottom;
|
||||
}
|
||||
return _stackView;
|
||||
}
|
||||
|
||||
- (UIButton *)arrangeMicButton {
|
||||
if (!_arrangeMicButton) {
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
YuMi/Resources/cp/level up 1.svga
Normal file
BIN
YuMi/Resources/cp/level up 1.svga
Normal file
Binary file not shown.
BIN
YuMi/Resources/cp/level up 2.svga
Normal file
BIN
YuMi/Resources/cp/level up 2.svga
Normal file
Binary file not shown.
BIN
YuMi/Resources/cp/level up 3.svga
Normal file
BIN
YuMi/Resources/cp/level up 3.svga
Normal file
Binary file not shown.
BIN
YuMi/Resources/cp/level up 4.svga
Normal file
BIN
YuMi/Resources/cp/level up 4.svga
Normal file
Binary file not shown.
BIN
YuMi/Resources/cp/level up 5.svga
Normal file
BIN
YuMi/Resources/cp/level up 5.svga
Normal file
Binary file not shown.
Reference in New Issue
Block a user