Files
SellyCloudSDK_demo/Example/SellyCloudSDK/Controllers/Home/AVLiveStreamCell.m
2026-03-01 15:59:27 +08:00

183 lines
6.4 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//
// AVLiveStreamCell.m
// AVDemo
//
#import "AVLiveStreamCell.h"
#import "AVLiveStreamModel.h"
#import <Masonry/Masonry.h>
#import <SDWebImage/SDWebImage.h>
@interface AVLiveStreamCell ()
@property (nonatomic, strong) UIImageView *thumbnailView;
@property (nonatomic, strong) UIView *overlayView;
@property (nonatomic, strong) UIImageView *playIcon;
@property (nonatomic, strong) UILabel *durationLabel;
@property (nonatomic, strong) UILabel *nameLabel;
@property (nonatomic, strong) UILabel *liveLabel;
@property (nonatomic, strong) UILabel *protocolLabel;
@end
@implementation AVLiveStreamCell
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self setupUI];
}
return self;
}
- (void)setupUI {
// 配置 Cell 背景
self.contentView.backgroundColor = [UIColor secondarySystemBackgroundColor];
self.contentView.layer.cornerRadius = 8;
self.contentView.clipsToBounds = YES;
// 创建缩略图
_thumbnailView = [[UIImageView alloc] init];
_thumbnailView.backgroundColor = [UIColor systemGrayColor];
_thumbnailView.contentMode = UIViewContentModeScaleAspectFill;
_thumbnailView.clipsToBounds = YES;
[self.contentView addSubview:_thumbnailView];
// 半透明遮罩层
_overlayView = [[UIView alloc] init];
_overlayView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.2];
[_thumbnailView addSubview:_overlayView];
// 播放图标
_playIcon = [[UIImageView alloc] initWithImage:[UIImage systemImageNamed:@"play.circle.fill"]];
_playIcon.tintColor = [UIColor whiteColor];
_playIcon.contentMode = UIViewContentModeScaleAspectFit;
_playIcon.layer.shadowColor = [UIColor blackColor].CGColor;
_playIcon.layer.shadowOffset = CGSizeMake(0, 2);
_playIcon.layer.shadowOpacity = 0.3;
_playIcon.layer.shadowRadius = 4;
[_thumbnailView addSubview:_playIcon];
// 直播时长标签
_durationLabel = [[UILabel alloc] init];
_durationLabel.font = [UIFont systemFontOfSize:12 weight:UIFontWeightMedium];
_durationLabel.textColor = [UIColor whiteColor];
_durationLabel.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6];
_durationLabel.textAlignment = NSTextAlignmentCenter;
_durationLabel.layer.cornerRadius = 4;
_durationLabel.clipsToBounds = YES;
[_thumbnailView addSubview:_durationLabel];
// 流名称标签
_nameLabel = [[UILabel alloc] init];
_nameLabel.font = [UIFont systemFontOfSize:14 weight:UIFontWeightSemibold];
_nameLabel.textColor = [UIColor labelColor];
_nameLabel.numberOfLines = 1;
[self.contentView addSubview:_nameLabel];
// 底部信息容器
UIView *infoContainerView = [[UIView alloc] init];
[self.contentView addSubview:infoContainerView];
// 直播状态标签
_liveLabel = [[UILabel alloc] init];
_liveLabel.text = @"🔴 直播中";
_liveLabel.font = [UIFont systemFontOfSize:11 weight:UIFontWeightMedium];
_liveLabel.textColor = [UIColor systemRedColor];
[infoContainerView addSubview:_liveLabel];
// 协议标签
_protocolLabel = [[UILabel alloc] init];
_protocolLabel.font = [UIFont systemFontOfSize:10 weight:UIFontWeightMedium];
_protocolLabel.textColor = [UIColor whiteColor];
_protocolLabel.backgroundColor = [UIColor systemBlueColor];
_protocolLabel.textAlignment = NSTextAlignmentCenter;
_protocolLabel.layer.cornerRadius = 3;
_protocolLabel.clipsToBounds = YES;
[infoContainerView addSubview:_protocolLabel];
// 布局
[_thumbnailView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.right.equalTo(self.contentView);
// 使用较低优先级的宽高比约束 3:4允许它在必要时被压缩
make.height.equalTo(_thumbnailView.mas_width).multipliedBy(4.0 / 3.0).priority(750);
}];
[_overlayView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(_thumbnailView);
}];
[_playIcon mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(_thumbnailView);
make.width.height.equalTo(@50);
}];
[_durationLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.equalTo(_thumbnailView).offset(-8);
make.right.equalTo(_thumbnailView).offset(-8);
make.height.equalTo(@20);
make.width.greaterThanOrEqualTo(@50);
}];
[_nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(_thumbnailView.mas_bottom).offset(8);
make.left.equalTo(self.contentView).offset(8);
make.right.equalTo(self.contentView).offset(-8);
}];
[infoContainerView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(_nameLabel.mas_bottom).offset(4);
make.left.equalTo(self.contentView).offset(8);
make.right.lessThanOrEqualTo(self.contentView).offset(-8);
make.bottom.lessThanOrEqualTo(self.contentView).offset(-8).priority(750);
// 移除 height 的硬性约束,让它根据内容自适应
}];
[_liveLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.bottom.equalTo(infoContainerView);
}];
[_protocolLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(_liveLabel.mas_right).offset(8);
make.centerY.equalTo(_liveLabel);
make.height.equalTo(@16);
make.width.greaterThanOrEqualTo(@40);
make.right.lessThanOrEqualTo(infoContainerView);
}];
}
- (void)configureWithModel:(AVLiveStreamModel *)model {
// 设置流名称
_nameLabel.text = model.displayName;
// 设置时长
_durationLabel.text = model.durationString;
// 设置协议标签
_protocolLabel.text = model.play_protocol.uppercaseString;
// 使用 SDWebImage 加载预览图
if (model.preview_image.length > 0) {
NSURL *imageURL = [NSURL URLWithString:model.preview_image];
[_thumbnailView sd_setImageWithURL:imageURL];
} else {
// 没有预览图,清空图片
_thumbnailView.image = nil;
}
}
- (void)prepareForReuse {
[super prepareForReuse];
// 取消之前的图片加载任务
[_thumbnailView sd_cancelCurrentImageLoad];
// 清空数据,防止复用时显示错误内容
_thumbnailView.image = nil;
_nameLabel.text = @"";
_durationLabel.text = @"";
_protocolLabel.text = @"";
}
@end