initial commit

This commit is contained in:
Caleb
2026-03-01 15:59:27 +08:00
commit a9e97d56cb
1426 changed files with 172367 additions and 0 deletions

View File

@@ -0,0 +1,182 @@
//
// 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