This commit is contained in:
启星
2025-11-21 16:17:05 +08:00
parent 7ac937ddbf
commit 8913ea6f48
283 changed files with 8474 additions and 800 deletions

View File

@@ -0,0 +1,29 @@
//
// QXRoomSongListCell.h
// QXLive
//
// Created by 启星 on 2025/6/9.
//
#import <UIKit/UIKit.h>
#import "QXSongListModel.h"
NS_ASSUME_NONNULL_BEGIN
@interface QXRoomSongListCell : UITableViewCell
@property (nonatomic,assign)BOOL isSearch;
@property (nonatomic,assign)BOOL isBgMusic;
@property (nonatomic,assign)BOOL isCompere;
@property (nonatomic,strong) QXSongListModel *model;
@property (nonatomic,strong) NSString *roomId;
@property (weak, nonatomic) IBOutlet UIImageView *coverImageView;
@property (weak, nonatomic) IBOutlet UILabel *songNameLabel;
@property (weak, nonatomic) IBOutlet UILabel *posterLabel;
@property (weak, nonatomic) IBOutlet UIButton *endBtn;
@property (weak, nonatomic) IBOutlet UIButton *upBtn;
@property (weak, nonatomic) IBOutlet UILabel *userNameLabel;
@property (nonatomic,copy)void(^moveSuccessBlock)(void);
+(instancetype)cellWithTableView:(UITableView *)tableView;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,112 @@
//
// QXRoomSongListCell.m
// QXLive
//
// Created by on 2025/6/9.
//
#import "QXRoomSongListCell.h"
#import "QXMineNetwork.h"
#import "QXAgoraEngine.h"
@implementation QXRoomSongListCell
+(instancetype)cellWithTableView:(UITableView *)tableView{
static NSString *cellId = @"QXRoomSongListCell";
QXRoomSongListCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (!cell) {
cell = [[NSBundle mainBundle] loadNibNamed:cellId owner:nil options:nil].lastObject;
cell.backgroundColor = [UIColor clearColor];
}
return cell;
}
-(void)setIsSearch:(BOOL)isSearch{
_isSearch = isSearch;
if (self.isBgMusic) {
self.upBtn.hidden = YES;
}else{
self.upBtn.hidden = isSearch;
}
if (isSearch) {
[self.endBtn setTitle:isSearch?QXText(@"点歌"):QXText(@"置顶") forState:(UIControlStateNormal)];
}else{
if (self.isBgMusic) {
self.endBtn.hidden = YES;
}else{
if (self.isCompere) {
self.endBtn.hidden = NO;
[self.endBtn setTitle:isSearch?QXText(@"点歌"):QXText(@"置顶") forState:(UIControlStateNormal)];
}else{
self.endBtn.hidden = YES;
self.upBtn.hidden = YES;
}
}
}
}
-(void)setIsBgMusic:(BOOL)isBgMusic{
_isBgMusic = isBgMusic;
}
- (IBAction)endAction:(id)sender {
if (self.isSearch) {
if (self.isBgMusic) {
showToast(@"点歌成功");
[[QXAgoraEngine sharedEngine] addBgMusic:self.model];
}else{
[QXMineNetwork selectedSongWithRoomId:self.roomId
user_id:[QXGlobal shareGlobal].loginModel.user_id
song_code:[NSString stringWithFormat:@"%ld",self.model.song_code]
song_name:self.model.song_name
singer:self.model.singer
poster:self.model.poster
duration:[NSString stringWithFormat:@"%ld",self.model.duration]
successBlock:^(NSDictionary * _Nonnull dict) {
showToast(@"点歌成功");
} failBlock:^(NSError * _Nonnull error, NSString * _Nonnull msg) {
showToast(msg);
}];
}
}else{
[self moveSongIsTop:YES];
}
}
- (IBAction)upAction:(id)sender {
[self moveSongIsTop:NO];
}
-(void)setIsCompere:(BOOL)isCompere{
_isCompere = isCompere;
// self.upBtn.hidden = !isCompere;
// self.endBtn.hidden = !isCompere;
}
-(void)moveSongIsTop:(BOOL)isTop{
MJWeakSelf
[QXMineNetwork moveSongWithRoomSongId:self.model.did type:isTop?@"2":@"1" successBlock:^(NSDictionary * _Nonnull dict) {
if (weakSelf.moveSuccessBlock) {
weakSelf.moveSuccessBlock();
}
showToast(@"移动成功");
} failBlock:^(NSError * _Nonnull error, NSString * _Nonnull msg) {
showToast(msg);
}];
}
-(void)setModel:(QXSongListModel *)model{
_model = model;
[self.coverImageView sd_setImageWithURL:[NSURL URLWithString:model.poster]];
NSString *time = [NSString stringWithFormat:@"%02ld:%02ld",model.duration/60,model.duration%60];
self.posterLabel.text = [NSString stringWithFormat:@"%@ %@",time,model.singer];
self.songNameLabel.text = model.song_name;
self.userNameLabel.text = model.nickname;
}
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
@end

View File

@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" rowHeight="163" id="KGk-i7-Jjw" customClass="QXRoomSongListCell">
<rect key="frame" x="0.0" y="0.0" width="466" height="163"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
<rect key="frame" x="0.0" y="0.0" width="466" height="163"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="dAY-R1-1Xw">
<rect key="frame" x="16" y="55.666666666666657" width="52" height="52"/>
<constraints>
<constraint firstAttribute="height" constant="52" id="Fmc-qu-edY"/>
<constraint firstAttribute="width" constant="52" id="xh7-0d-x9a"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="layer.masksToBounds" value="YES"/>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="3"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cEo-4m-Uk0">
<rect key="frame" x="74" y="59.666666666666657" width="35.333333333333343" height="18"/>
<constraints>
<constraint firstAttribute="height" constant="18" id="b1c-op-Skx"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="王富贵" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SNA-M2-7Y8">
<rect key="frame" x="74" y="85.666666666666671" width="200" height="18"/>
<constraints>
<constraint firstAttribute="height" constant="18" id="XKi-Bc-Kyd"/>
<constraint firstAttribute="width" constant="200" id="cZF-LW-Eez"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="prN-Cg-NVp">
<rect key="frame" x="398" y="66.666666666666671" width="52" height="30"/>
<color key="backgroundColor" red="0.050980392156862744" green="1" blue="0.72549019607843135" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="width" constant="52" id="ErL-3b-xUl"/>
<constraint firstAttribute="height" constant="30" id="M8O-GG-Lcl"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="结束">
<color key="titleColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
</state>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="layer.masksToBounds" value="YES"/>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="15"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<action selector="endAction:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="Ryq-am-gZg"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="nCl-nA-G1H">
<rect key="frame" x="353" y="64" width="35" height="35"/>
<constraints>
<constraint firstAttribute="height" constant="35" id="bWm-9A-ja7"/>
<constraint firstAttribute="width" constant="35" id="l70-bk-etp"/>
</constraints>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" image="room_song_up"/>
<connections>
<action selector="upAction:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="lXk-rU-fQZ"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="wAY-Bl-81T">
<rect key="frame" x="284" y="94.666666666666671" width="59" height="0.0"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstItem="SNA-M2-7Y8" firstAttribute="leading" secondItem="cEo-4m-Uk0" secondAttribute="leading" id="1ia-Qn-gkV"/>
<constraint firstItem="wAY-Bl-81T" firstAttribute="centerY" secondItem="SNA-M2-7Y8" secondAttribute="centerY" id="5fU-Uw-Sf8"/>
<constraint firstAttribute="trailing" secondItem="prN-Cg-NVp" secondAttribute="trailing" constant="16" id="DSL-WP-A3K"/>
<constraint firstItem="cEo-4m-Uk0" firstAttribute="top" secondItem="dAY-R1-1Xw" secondAttribute="top" constant="4" id="Kno-Zg-rp2"/>
<constraint firstItem="SNA-M2-7Y8" firstAttribute="bottom" secondItem="dAY-R1-1Xw" secondAttribute="bottom" constant="-4" id="SXZ-zo-2j2"/>
<constraint firstItem="wAY-Bl-81T" firstAttribute="leading" secondItem="SNA-M2-7Y8" secondAttribute="trailing" constant="10" id="VB3-n2-Huh"/>
<constraint firstItem="cEo-4m-Uk0" firstAttribute="leading" secondItem="dAY-R1-1Xw" secondAttribute="trailing" constant="6" id="YcA-Ji-ToE"/>
<constraint firstItem="nCl-nA-G1H" firstAttribute="leading" secondItem="wAY-Bl-81T" secondAttribute="trailing" constant="10" id="cVf-2A-n8b"/>
<constraint firstItem="nCl-nA-G1H" firstAttribute="centerY" secondItem="prN-Cg-NVp" secondAttribute="centerY" id="fbA-GF-fge"/>
<constraint firstItem="dAY-R1-1Xw" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="16" id="vH3-3z-2SL"/>
<constraint firstItem="prN-Cg-NVp" firstAttribute="leading" secondItem="nCl-nA-G1H" secondAttribute="trailing" constant="10" id="ze3-qs-gsC"/>
</constraints>
</tableViewCellContentView>
<viewLayoutGuide key="safeArea" id="aW0-zy-SZf"/>
<constraints>
<constraint firstItem="prN-Cg-NVp" firstAttribute="centerY" secondItem="aW0-zy-SZf" secondAttribute="centerY" id="XhU-js-NUE"/>
<constraint firstItem="dAY-R1-1Xw" firstAttribute="centerY" secondItem="aW0-zy-SZf" secondAttribute="centerY" id="liM-Yh-tyy"/>
</constraints>
<connections>
<outlet property="coverImageView" destination="dAY-R1-1Xw" id="13P-C0-xc8"/>
<outlet property="endBtn" destination="prN-Cg-NVp" id="fEr-hy-Kvr"/>
<outlet property="posterLabel" destination="SNA-M2-7Y8" id="c1y-Cd-Ze0"/>
<outlet property="songNameLabel" destination="cEo-4m-Uk0" id="EIf-pB-ruW"/>
<outlet property="upBtn" destination="nCl-nA-G1H" id="e7A-2b-WE7"/>
<outlet property="userNameLabel" destination="wAY-Bl-81T" id="jHd-10-kev"/>
</connections>
<point key="canvasLocation" x="250.38167938931298" y="40.492957746478872"/>
</tableViewCell>
</objects>
<resources>
<image name="room_song_up" width="16" height="16"/>
</resources>
</document>

View File

@@ -0,0 +1,22 @@
//
// QXRoomSongListSubView.h
// QXLive
//
// Created by 启星 on 2025/6/9.
//
#import <UIKit/UIKit.h>
#import "JXCategoryView.h"
NS_ASSUME_NONNULL_BEGIN
@interface QXRoomSongListSubView : UIView<JXCategoryListContentViewDelegate>
@property (nonatomic,assign)BOOL isSearch;
@property (nonatomic,assign)BOOL isBgMusic;
@property (nonatomic,assign)BOOL isCompere;
@property (nonatomic,strong)NSString* roomId;
@property (nonatomic,copy)void(^beiginEditBlock)(void);
@property (nonatomic,copy)void(^endEditBlock)(void);
@property (nonatomic,strong)UITableView *tableView;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,210 @@
//
// QXRoomSongListSubView.m
// QXLive
//
// Created by on 2025/6/9.
//
#import "QXRoomSongListSubView.h"
#import "QXRoomSongListCell.h"
#import "QXAgoraEngine.h"
#import "QXMineNetwork.h"
@interface QXRoomSongListSubView()<UITableViewDataSource,UITableViewDelegate,UITextFieldDelegate>
@property (nonatomic,strong)UIView *searchBgView;
@property (nonatomic,strong)UIImageView *searchIcon;
@property (nonatomic,strong)UITextField *textField;
@property (nonatomic,strong)NSMutableArray *dataArray;
@property (nonatomic,assign)NSInteger page;
@end
@implementation QXRoomSongListSubView
-(UIView *)listView{
return self;
}
-(void)listWillAppear{
if (!self.isSearch) {
[self getSongList];
}
}
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self initSubviews];
}
return self;
}
-(void)initSubviews{
self.page = 1;
self.searchBgView = [[UIView alloc] initWithFrame:CGRectMake(16, 6, self.width-32, 35)];
self.searchBgView.backgroundColor = RGB16(0xEFF2F8);
[self.searchBgView addRoundedCornersWithRadius:17.5];
[self addSubview:self.searchBgView];
self.searchIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"room_song_search"]];
self.searchIcon.frame = CGRectMake(10, 10, 15, 15);
[self.searchBgView addSubview:self.searchIcon];
self.textField = [[UITextField alloc] initWithFrame:CGRectMake(self.searchIcon.right+2, 0, self.width-self.searchIcon.right-2-10, 35)];
self.textField.textColor = RGB16(0x333333);
self.textField.placeholder = QXText(@"请输入歌名搜索");
self.textField.font = [UIFont systemFontOfSize:13];
self.textField.returnKeyType = UIReturnKeyDone;
[self.textField addTarget:self action:@selector(textDidChange:) forControlEvents:UIControlEventEditingChanged];
self.textField.delegate = self;
[self.searchBgView addSubview:self.textField];
self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, self.searchBgView.bottom+10, self.width, self.height-self.searchBgView.bottom-10) style:(UITableViewStylePlain)];
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView.backgroundColor = [UIColor clearColor];
self.tableView.rowHeight = 72;
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
MJWeakSelf
self.tableView.mj_footer = [MJRefreshBackStateFooter footerWithRefreshingBlock:^{
weakSelf.page++;
[weakSelf getSongList];
}];
self.tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
weakSelf.page = 1;
[weakSelf getSongList];
}];
[self addSubview:self.tableView];
// [self getSongList];
}
-(void)setIsBgMusic:(BOOL)isBgMusic{
_isBgMusic = isBgMusic;
[self.tableView reloadData];
}
#pragma mark - UITextFieldDelegate
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
-(void)textFieldDidBeginEditing:(UITextField *)textField{
if (self.beiginEditBlock) {
self.beiginEditBlock();
}
}
-(void)textFieldDidEndEditing:(UITextField *)textField{
if (self.endEditBlock) {
self.endEditBlock();
}
}
-(void)setIsSearch:(BOOL)isSearch{
_isSearch = isSearch;
self.searchBgView.hidden = !isSearch;
self.tableView.frame = CGRectMake(0, isSearch?self.searchBgView.bottom+10:6, self.width, isSearch?(self.height-self.searchBgView.bottom-10):self.height - 6);
}
-(void)setRoomId:(NSString *)roomId{
_roomId = roomId;
[self getSongList];
}
-(void)getSongList{
MJWeakSelf
if (self.isSearch) {
if (self.textField.text.length == 0) {
return;
}
[[QXAgoraEngine sharedEngine] searchSongWithKeyword:self.textField.text page:self.page resultBlock:^(NSArray<AgoraMusic *> * _Nonnull songList, BOOL isReload) {
dispatch_async(dispatch_get_main_queue(), ^{
if (isReload) {
[weakSelf.dataArray removeAllObjects];
}
for (AgoraMusic*music in songList) {
if ([music.singer isEqualToString:@"彭丽媛"]) {
continue;
}
QXSongListModel *model = [[QXSongListModel alloc] init];
model.song_code = music.songCode;
model.song_name = music.name;
model.poster = music.poster;
model.singer = music.singer;
model.duration = music.durationS;
[weakSelf.dataArray addObject:model];
}
[weakSelf.tableView reloadData];
if (songList.count == 0) {
weakSelf.tableView.mj_footer.state = MJRefreshStateNoMoreData;
}else{
[weakSelf.tableView.mj_footer endRefreshing];
}
[weakSelf.tableView.mj_header endRefreshing];
});
}];
}else{
if (self.isBgMusic) {
self.dataArray = [NSMutableArray arrayWithArray:[QXAgoraEngine sharedEngine].bgMusicArray];
[self.tableView reloadData];
[self.tableView.mj_header endRefreshing];
self.tableView.mj_footer.state = MJRefreshStateNoMoreData;
}else{
[QXMineNetwork roomSongListWithRoomId:self.roomId successBlock:^(NSArray<QXSongListModel *> * _Nonnull list) {
[weakSelf.dataArray removeAllObjects];
[weakSelf.dataArray addObjectsFromArray:list];
[weakSelf.tableView reloadData];
weakSelf.tableView.mj_footer.state = MJRefreshStateNoMoreData;
[weakSelf.tableView.mj_header endRefreshing];
} failBlock:^(NSError * _Nonnull error, NSString * _Nonnull msg) {
[weakSelf.tableView.mj_header endRefreshing];
}];
}
}
}
-(void)textDidChange:(UITextField*)textField{
if ([self isMarkedText]) {
//
QXLOG(@"中文输入中,不回调");
return;
}
QXLOG(@"中文输入结束,回调");
[[SDImageCache sharedImageCache] clearMemory];
self.page = 0;
[self getSongList];
}
- (BOOL)isMarkedText {
UITextRange *markedTextRange = self.textField.markedTextRange;
return markedTextRange && ![markedTextRange isEmpty];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.dataArray.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
MJWeakSelf
QXRoomSongListCell *cell = [QXRoomSongListCell cellWithTableView:tableView];
cell.isBgMusic = self.isBgMusic;
cell.isCompere = self.isCompere;
cell.roomId = self.roomId;
cell.isSearch = self.isSearch;
cell.model = [self.dataArray objectAtIndex:indexPath.row];
cell.moveSuccessBlock = ^{
[weakSelf getSongList];
};
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
// QXSongListModel *model = self.dataArray[indexPath.row];
// [[QXAgoraEngine sharedEngine] ktv_EndSing];
// [[QXAgoraEngine sharedEngine] ktv_StartSing:YES withSong:model];
}
-(NSMutableArray *)dataArray{
if (!_dataArray) {
_dataArray = [NSMutableArray array];
}
return _dataArray;
}
@end

View File

@@ -0,0 +1,19 @@
//
// QXRoomSongListView.h
// QXLive
//
// Created by 启星 on 2025/6/9.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface QXRoomSongListView : UIView
@property (nonatomic,assign)BOOL isBgMusic;
@property (nonatomic,assign)BOOL isCompere;
@property (nonatomic,strong)NSString *roomId;
-(void)showInView:(UIView *)view;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,117 @@
//
// QXRoomSongListView.m
// QXLive
//
// Created by on 2025/6/9.
//
#import "QXRoomSongListView.h"
#import "JXCategoryView.h"
#import "QXRoomSongListSubView.h"
@interface QXRoomSongListView()<UIGestureRecognizerDelegate,JXCategoryViewDelegate,JXCategoryListContainerViewDelegate>
@property (nonatomic,strong)UIView *bgView;
@property (nonatomic,strong)JXCategoryTitleView *categoryView;
@property (nonatomic,strong)JXCategoryListContainerView *containerView;
@end
@implementation QXRoomSongListView
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self initSubviews];
}
return self;
}
-(void)initSubviews{
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hide)];
tap.delegate = self;
[self addGestureRecognizer:tap];
self.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.3];
self.bgView = [[UIView alloc] initWithFrame:CGRectMake(0, ScaleWidth(144), SCREEN_WIDTH, kSafeAreaBottom+ScaleWidth(429))];
self.bgView.backgroundColor = UIColor.whiteColor;
[self.bgView addRoundedCornersWithRadius:16 byRoundingCorners:(UIRectCornerTopLeft|UIRectCornerTopRight)];
[self addSubview:self.bgView];
self.categoryView = [[JXCategoryTitleView alloc] init];
self.categoryView.frame = CGRectMake((self.width-150)/2,0,150, 44);
self.categoryView.delegate = self;
self.categoryView.titles = @[QXText(@"点歌"),QXText(@"已点")];
self.categoryView.titleSelectedColor = [UIColor colorWithHexString:@"#33333"];
self.categoryView.titleColor = [UIColor colorWithHexString:@"#999999"];
self.categoryView.cellWidth = 51;
self.categoryView.cellSpacing = 20;
self.categoryView.contentEdgeInsetLeft = 8;
// self.categoryView.contentEdgeInsetRight = 8;
// self.categoryView.titleLabelZoomScale = 1.1;
self.categoryView.titleLabelZoomEnabled = YES;
self.categoryView.titleFont = [UIFont boldSystemFontOfSize:14];
self.categoryView.titleSelectedFont = [UIFont boldSystemFontOfSize:16];
self.categoryView.averageCellSpacingEnabled = YES;
// JXCategoryIndicatorImageView *indicatorView = [[JXCategoryIndicatorImageView alloc] init];
// indicatorView.indicatorImageView.image = [[UIImage imageNamed:@"home_slider"] imageByTintColor:[UIColor whiteColor]];
// indicatorView.indicatorImageViewSize = CGSizeMake(40, 8);
// indicatorView.verticalMargin = 11;
// self.categoryView.indicators = @[indicatorView];
self.containerView = [[JXCategoryListContainerView alloc] initWithType:(JXCategoryListContainerType_ScrollView) delegate:self];
self.containerView.frame = CGRectMake(0, 44, self.width, self.bgView.height-44);
[self.bgView addSubview:self.categoryView];
[self.bgView addSubview:self.containerView];
self.categoryView.listContainer = self.containerView;
}
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
return touch.view == self;
}
- (NSInteger)numberOfListsInlistContainerView:(JXCategoryListContainerView *)listContainerView{
return 2;
}
-(void)setIsBgMusic:(BOOL)isBgMusic{
_isBgMusic = isBgMusic;
}
- (id<JXCategoryListContentViewDelegate>)listContainerView:(JXCategoryListContainerView *)listContainerView initListForIndex:(NSInteger)index{
QXRoomSongListSubView *vc = [[QXRoomSongListSubView alloc] initWithFrame:CGRectMake(0, 0, self.width, self.bgView.height-44)];
vc.isBgMusic = self.isBgMusic;
vc.isCompere = self.isCompere;
if (index == 0) {
vc.isSearch = YES;
}else{
vc.isSearch = NO;
}
vc.roomId = self.roomId;
vc.beiginEditBlock = ^{
[UIView animateWithDuration:0.3 animations:^{
self.bgView.y = kSafeAreaTop+90;
} completion:^(BOOL finished) {
}];
};
vc.endEditBlock = ^{
[UIView animateWithDuration:0.3 animations:^{
self.bgView.y = SCREEN_HEIGHT-ScaleWidth(429)-kSafeAreaBottom;
} completion:^(BOOL finished) {
}];
};
return vc;
}
-(void)showInView:(UIView *)view{
[self.categoryView reloadData];
self.bgView.y = SCREEN_HEIGHT;
[view addSubview:self];
[UIView animateWithDuration:0.3 animations:^{
self.bgView.y = SCREEN_HEIGHT- ScaleWidth(429)-kSafeAreaBottom;
}];
}
-(void)hide{
[UIView animateWithDuration:0.3 animations:^{
self.bgView.y = SCREEN_HEIGHT;
} completion:^(BOOL finished) {
[self removeFromSuperview];
}];
}
@end