// // SPSBBroadcastView.m // 我的社保 // // Created by shanp on 2021/5/12. // #import "SPSBBroadcastView.h" #import "SPSBUIGeneralHeader.h" #define LimitWidth (jxh_screenWidth() - 70) static NSString *const space = @" "; static const NSInteger SPConsultationBroadcastViewHeight = 45; @interface SPSBBroadcastView () { UILabel *_broadcastLabel; void (^_reloadDataAction)(CGFloat height); UIView *_animationView; UILabel *_animationLabel; CGFloat _spaceWidth; CGFloat _broadcastWidth; bool _isAnimation; } @end @implementation SPSBBroadcastView - (instancetype)initWithReloadDataAction:(void (^)(CGFloat height))reloadDataAction { self = [super init]; if (!self) return nil; _reloadDataAction = reloadDataAction; self.backgroundColor = spsb_FDF8EC_color(); self.layer.masksToBounds = true; UIButton *deleteButton = [UIButton convenienceWithTarget:self action:@selector(deleteBroadcastView)]; [self addSubview:deleteButton]; [deleteButton makeConstraints:^(JXHConstraintMaker *make) { make.top.and.trailing.equalTo(0); make.size.equalTo(CGSizeMake(45, 45)); }]; UIImageView *deleteImageView = [[UIImageView alloc] initWithImage:jxh_getImage(notice_close)]; [deleteButton addSubview:deleteImageView]; [deleteImageView makeConstraints:^(JXHConstraintMaker *make) { make.size.equalTo(CGSizeMake(20, 20)); make.center.equalTo(deleteButton); }]; _broadcastLabel = [UILabel convenienceWithFont:spsb_font(13) text:@"" textColor:spsb_FF801A_color()]; _broadcastLabel.backgroundColor = spsb_FDF8EC_color(); [self addSubview:_broadcastLabel]; [_broadcastLabel makeConstraints:^(JXHConstraintMaker *make) { make.leading.equalTo(15); make.centerY.equalTo(self); make.trailing.equalTo(-45); }]; _animationView = [[UIView alloc] init]; _animationView.layer.masksToBounds = true; _animationView.backgroundColor = spsb_FDF8EC_color(); [self addSubview:_animationView]; [_animationView makeConstraints:^(JXHConstraintMaker *make) { make.top.and.bottom.equalTo(0); make.leading.equalTo(15); make.trailing.equalTo(-45); }]; _animationLabel = [UILabel convenienceWithFont:spsb_font(13) text:@"" textColor:spsb_FF801A_color()]; _animationLabel.backgroundColor = spsb_FDF8EC_color(); [_animationView addSubview:_animationLabel]; [_animationLabel makeConstraints:^(JXHConstraintMaker *make) { make.leading.and.top.and.bottom.equalTo(0); }]; _animationLabel.text = space; [_animationLabel sizeToFit]; _spaceWidth = _animationLabel.bounds.size.width; return self; } - (void)deleteBroadcastView { _animationView.hidden = true; [_animationLabel.layer removeAnimationForKey:@"rollingAnimation"]; _isAnimation = false; _reloadDataAction(0); } - (void)animationBeginFirst:(bool)flag { _isAnimation = true; CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; if (flag) { CGFloat baseTime = (_broadcastWidth + _spaceWidth) / 50; CGFloat delay = 1 / (baseTime + 1); //设定关键帧位置,必须含起始与终止位置 animation.values = @[[NSValue valueWithCGPoint:CGPointMake(_broadcastWidth + _spaceWidth / 2, SPConsultationBroadcastViewHeight / 2)], [NSValue valueWithCGPoint:CGPointMake(_broadcastWidth + _spaceWidth / 2, SPConsultationBroadcastViewHeight / 2)], [NSValue valueWithCGPoint:CGPointMake(-_spaceWidth / 2, SPConsultationBroadcastViewHeight / 2)]]; //设定每个关键帧的时长,如果没有显式地设置,则默认每个帧的时间=总duration/(values.count - 1) animation.keyTimes = @[[NSNumber numberWithFloat:0.0], [NSNumber numberWithFloat:delay], [NSNumber numberWithFloat:1]]; animation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]]; animation.delegate = self; animation.calculationMode = kCAAnimationLinear; animation.duration = baseTime + 1; } else { //设定关键帧位置,必须含起始与终止位置 animation.values = @[[NSValue valueWithCGPoint:CGPointMake(_broadcastWidth + _spaceWidth / 2, SPConsultationBroadcastViewHeight / 2)], [NSValue valueWithCGPoint:CGPointMake(-_spaceWidth / 2, SPConsultationBroadcastViewHeight / 2)]]; //设定每个关键帧的时长,如果没有显式地设置,则默认每个帧的时间=总duration/(values.count - 1) animation.keyTimes = @[[NSNumber numberWithFloat:0.0], [NSNumber numberWithFloat:1]]; animation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]]; animation.delegate = self; animation.calculationMode = kCAAnimationLinear; animation.duration = (_broadcastWidth + _spaceWidth) / 50; } [_animationLabel.layer addAnimation:animation forKey:@"rollingAnimation"]; } - (void)animationDidStop:(CAAnimation *)anim finished:(bool)flag { if (flag) { [_animationLabel.layer removeAnimationForKey:@"rollingAnimation"]; [self animationBeginFirst:false]; } } - (void)stopAnimation { if (_isAnimation) { [_animationLabel.layer removeAnimationForKey:@"rollingAnimation"]; } } - (void)beginAnimation { if (_isAnimation) { [self animationBeginFirst:true]; } } - (void)reloadData:(nullable NSString *)broadcastString { if (nil == broadcastString || broadcastString.length == 0) { [self deleteBroadcastView]; return; } [_animationLabel.layer removeAnimationForKey:@"rollingAnimation"]; _animationLabel.text = broadcastString; [_animationLabel sizeToFit]; _broadcastWidth = _animationLabel.bounds.size.width; if (_broadcastWidth > LimitWidth) { _animationLabel.text = [NSString stringWithFormat:@"%@%@%@", broadcastString, space, broadcastString]; [_animationLabel sizeToFit]; _animationView.hidden = false; [self animationBeginFirst:true]; } else { _animationView.hidden = true; _isAnimation = false; } _broadcastLabel.text = broadcastString; CGFloat height = SPConsultationBroadcastViewHeight; if ([broadcastString isEqualToString:@""]) { height = 0; } _reloadDataAction(height); } @end #undef LimitWidth