Files
peko-ios/YuMi/Modules/YMMine/View/SubViews/CPGiftBanner.m

244 lines
8.6 KiB
Objective-C

//
// CPGiftBanner.m
// YuMi
//
// Created by P on 2024/9/23.
//
#import "CPGiftBanner.h"
#import <POP.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, strong) AttachmentModel *bannerAttachment;
@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:YMLocalizedString(@"Combo_0")];
UILabel *label_2 = [self labelWith:[NSString stringWithFormat:@"CP %@", YMLocalizedString(@"XPWishGiftInfoView1")]];
[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);
// CGFloat topSpace = kGetScaleWidth(67);
CPGiftBanner *bannerView = [[CPGiftBanner alloc] initWithFrame:CGRectMake(KScreenWidth, 0, width, height)];
bannerView.bannerAttachment = attachment;
bannerView.completeDisplay = complete;
[superView addSubview:bannerView];
@kWeakify(bannerView);
// 使用 POP 动画移动 banner 到目标位置
[bannerView popEnterAnimation:^(BOOL finished) {
if (finished) {
@kStrongify(bannerView);
[bannerView addNotification];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[bannerView popLeaveAnimation:^(bool finished) {
if (bannerView.completeDisplay) {
bannerView.completeDisplay();
}
[bannerView removeNotification];
[bannerView removeFromSuperview];
}];
});
}
}];
}
- (void)handleTapNotification:(NSNotification *)note {
NSValue *value = note.userInfo[@"point"];
CGPoint point = [value CGPointValue];
// 将 banner 中的点转换为屏幕坐标系
CGPoint screenPoint = [self convertPoint:point toView:nil];
// 发送通知给 FunctionContainer 处理,传递屏幕坐标
[[NSNotificationCenter defaultCenter] postNotificationName:@"BannerTapToFunctionContainer"
object:nil
userInfo:@{@"point": [NSValue valueWithCGPoint:screenPoint]}];
}
- (void)handleSwipeNotification {
[self dismissBanner];
}
- (void)addNotification {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleSwipeNotification)
name:@"SwipeOutBanner"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleTapNotification:)
name:@"TapBanner"
object:nil];
}
- (void)removeNotification {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)dismissBanner {
[self pop_removeAllAnimations]; // 停止所有动画
[self popLeaveAnimation:^(bool finished) {
if (self.completeDisplay) {
self.completeDisplay();
}
[self removeFromSuperview];
}];
}
- (void)popEnterAnimation:(void(^)(BOOL finished))finish {
NSInteger height = kGetScaleWidth(145);
POPSpringAnimation *enterAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewFrame];
enterAnimation.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, KScreenWidth, height)];
enterAnimation.springBounciness = 10; // 弹性系数
enterAnimation.springSpeed = 12; // 动画速度
enterAnimation.completionBlock = ^(POPAnimation *anim, BOOL finished) {
if (finish) {
finish(finished);
}
};
[self pop_addAnimation:enterAnimation forKey:@"enterAnimation"];
}
- (void)popLeaveAnimation:(void(^)(bool finished))finish {
NSInteger height = kGetScaleWidth(145);
POPBasicAnimation *exitAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewFrame];
exitAnimation.toValue = [NSValue valueWithCGRect:CGRectMake(-KScreenWidth, 0, KScreenWidth, height)];
exitAnimation.duration = 0.25; // 动画持续时间
exitAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
exitAnimation.completionBlock = ^(POPAnimation *anim, BOOL finished) {
if (finish) {
finish(finished);
}
};
[self pop_addAnimation:exitAnimation forKey:@"exitAnimation"];
}
#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