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

@@ -24,6 +24,8 @@ NS_ASSUME_NONNULL_BEGIN
imageurl :图片名称或链接 imageurl :图片名称或链接
*/ */
-(void)updateBgImage:(NSString*)imageUrl; -(void)updateBgImage:(NSString*)imageUrl;
-(void)updateBackImage:(UIImage *)image;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@@ -82,6 +82,10 @@
self.bgImageView.image = [UIImage imageNamed:imageUrl]; self.bgImageView.image = [UIImage imageNamed:imageUrl];
} }
} }
-(void)updateBackImage:(UIImage *)image{
[self.backBtn setImage:image forState:(UIControlStateNormal)];
}
-(UIImageView *)bgImageView{ -(UIImageView *)bgImageView{
if (!_bgImageView) { if (!_bgImageView) {
_bgImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)]; _bgImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)];

16
QXLive/Base/QXButton.h Normal file
View File

@@ -0,0 +1,16 @@
//
// QXButton.h
// QXLive
//
// Created by 启星 on 2025/11/20.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface QXButton : UIButton
@property (nonatomic,strong)id object;
@end
NS_ASSUME_NONNULL_END

20
QXLive/Base/QXButton.m Normal file
View File

@@ -0,0 +1,20 @@
//
// QXButton.m
// QXLive
//
// Created by on 2025/11/20.
//
#import "QXButton.h"
@implementation QXButton
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
@end

View File

@@ -108,6 +108,10 @@ typedef void (^showFinishBlock)(void);
-(void)finishTask; -(void)finishTask;
-(void)vibrationFeedback; -(void)vibrationFeedback;
-(void)dirfViewDidToBackground;
-(void)dirfViewBecomeToFront;
@end @end

View File

@@ -23,6 +23,12 @@
#import "QXRedPacketManager.h" #import "QXRedPacketManager.h"
#import "QXGiftDisplayManager.h" #import "QXGiftDisplayManager.h"
#import "QXDrifNobilityJoinRoomView.h"
#import "QXDrifRoomHourRankView.h"
#import "QXGiftDriftView.h"
#import "QXMeetActivityDriftView.h"
#import "QXRedPacketDriftView.h"
@interface QXGlobal() @interface QXGlobal()
@property (nonatomic,assign)BOOL isLogin; @property (nonatomic,assign)BOOL isLogin;
@@ -309,6 +315,8 @@
[[QXRedPacketManager sharedManager] destoryRedpacketInfo]; [[QXRedPacketManager sharedManager] destoryRedpacketInfo];
/// ///
[[QXGiftDisplayManager sharedManager] clearAll]; [[QXGiftDisplayManager sharedManager] clearAll];
///
[[QXDrifNobilityJoinRoomView shareView] dirfViewDidToBackground];
/// ///
[[QXGiftPlayerManager shareManager] destroyEffectSvga]; [[QXGiftPlayerManager shareManager] destroyEffectSvga];
/// 退 /// 退
@@ -364,4 +372,15 @@
} }
return _offLineDict; return _offLineDict;
} }
-(void)dirfViewDidToBackground{
[[QXDrifNobilityJoinRoomView shareView] dirfViewDidToBackground];
[[QXDrifRoomHourRankView shareView] dirfViewDidToBackground];
[[QXGiftDriftView shareView] dirfViewDidToBackground];
[[QXMeetActivityDriftView shareView] dirfViewDidToBackground];
[[QXRedPacketDriftView shareView] dirfViewDidToBackground];
}
-(void)dirfViewBecomeToFront{
}
@end @end

View File

@@ -145,6 +145,15 @@
cell.model = model; cell.model = model;
return cell; return cell;
} }
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
QXExpansionCell *eCell = (QXExpansionCell *)cell;
[eCell nameStartAnimate];
}
-(void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
QXExpansionCell *eCell = (QXExpansionCell *)cell;
[eCell nameStopAnimate];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
QXUserHomeModel *model = self.dataArray[indexPath.row]; QXUserHomeModel *model = self.dataArray[indexPath.row];
NSArray *imgArr; NSArray *imgArr;
@@ -154,7 +163,7 @@
// NSArray * // NSArray *
CGFloat itemH = 94; CGFloat itemH = 94;
if (imgArr.count == 1) { if (imgArr.count == 1) {
itemH = (SCREEN_WIDTH-15-15-15)/2 + 94; itemH = (SCREEN_WIDTH-15-15-15)/2 + 94+10;
}else if(imgArr.count > 1){ }else if(imgArr.count > 1){
if (imgArr.count > 3) { if (imgArr.count > 3) {
itemH = (SCREEN_WIDTH-16*2-12*2-10*2)/3*2+10+94+ScaleWidth(10); itemH = (SCREEN_WIDTH-16*2-12*2-10*2)/3*2+10+94+ScaleWidth(10);

View File

@@ -8,20 +8,22 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import "QXUserModel.h" #import "QXUserModel.h"
#import "QXSeatHeaderView.h" #import "QXSeatHeaderView.h"
#import "CKShimmerLabel.h"
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@interface QXExpansionCell : UITableViewCell @interface QXExpansionCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UIView *bgView; @property (weak, nonatomic) IBOutlet UIView *bgView;
@property (weak, nonatomic) IBOutlet QXSeatHeaderView *avatarImgV; @property (weak, nonatomic) IBOutlet QXSeatHeaderView *avatarImgV;
@property (weak, nonatomic) IBOutlet UILabel *nicknameLab; @property (weak, nonatomic) IBOutlet CKShimmerLabel *nameLabel;
@property (weak, nonatomic) IBOutlet UIImageView *levelImgV;
@property (weak, nonatomic) IBOutlet UILabel *ageLabel; @property (weak, nonatomic) IBOutlet UILabel *ageLabel;
@property (weak, nonatomic) IBOutlet UIButton *followBtn; @property (weak, nonatomic) IBOutlet UIButton *followBtn;
@property (weak, nonatomic) IBOutlet UIView *imgsBgView; @property (weak, nonatomic) IBOutlet UIView *imgsBgView;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *imgsBgViewHeightCon; @property (weak, nonatomic) IBOutlet NSLayoutConstraint *imgsBgViewHeightCon;
@property (weak, nonatomic) IBOutlet UIImageView *sexImageView; @property (weak, nonatomic) IBOutlet UIImageView *sexImageView;
@property (nonatomic, strong) QXUserHomeModel *model; @property (nonatomic, strong) QXUserHomeModel *model;
-(void)nameStartAnimate;
-(void)nameStopAnimate;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@@ -37,6 +37,12 @@
make.size.mas_equalTo(CGSizeMake(imgWidth, imgWidth)); make.size.mas_equalTo(CGSizeMake(imgWidth, imgWidth));
}]; }];
} }
self.nameLabel.textColor = RGB16(0x212121);
self.nameLabel.shimmerWidth = 20;
self.nameLabel.shimmerRadius = 20;
self.nameLabel.durationTime = 1;;
self.nameLabel.font = [UIFont boldSystemFontOfSize:15];
[self.nameLabel stopShimmer];
} }
- (IBAction)chatAction:(id)sender { - (IBAction)chatAction:(id)sender {
if (self.model.room_id.intValue > 0) { if (self.model.room_id.intValue > 0) {
@@ -55,11 +61,13 @@
self.avatarImgV.nobilityImageView.image = nil; self.avatarImgV.nobilityImageView.image = nil;
} }
if ([model.nickname_color isExist]) { if ([model.nickname_color isExist]) {
self.nicknameLab.textColor = [UIColor colorWithHexString:model.nickname_color]; self.nameLabel.shimmerColor = [UIColor colorWithHexString:model.nickname_color];
// [self.nameLabel startShimmer];
}else{ }else{
self.nicknameLab.textColor = RGB16(0x212121); self.nameLabel.shimmerColor = [UIColor clearColor];
// [self.nameLabel stopShimmer];
} }
self.nicknameLab.text = model.nickname; self.nameLabel.text = model.nickname;
self.ageLabel.text = [NSString stringWithFormat:@"%ld岁 ip属地: %@",[model.birthday ageWithDateOfBirth],model.loginip]; self.ageLabel.text = [NSString stringWithFormat:@"%ld岁 ip属地: %@",[model.birthday ageWithDateOfBirth],model.loginip];
CGFloat imgWidth = (SCREEN_WIDTH-16*2-12*2-10*2)/3; CGFloat imgWidth = (SCREEN_WIDTH-16*2-12*2-10*2)/3;
UIImageView *firstImgV = self.imgViewsArray.firstObject; UIImageView *firstImgV = self.imgViewsArray.firstObject;
@@ -112,6 +120,31 @@
self.followBtn.selected = NO; self.followBtn.selected = NO;
} }
} }
-(void)nameStartAnimate{
if ([self.model.nickname_color isExist]) {
[self.nameLabel stopShimmer];
[self.nameLabel layoutSubviews];
self.nameLabel.shimmerWidth = 20;
self.nameLabel.shimmerRadius = 20;
self.nameLabel.durationTime = 1;
self.nameLabel.shimmerColor = [UIColor colorWithHexString:self.model.nickname_color];
[self.nameLabel startShimmer];
}
// else{
// self.nameLabel.shimmerColor = [UIColor clearColor];
// [self.nameLabel stopShimmer];
// }
}
-(void)nameStopAnimate{
if ([self.model.nickname_color isExist]) {
self.nameLabel.shimmerColor = [UIColor colorWithHexString:self.model.nickname_color];
[self.nameLabel stopShimmer];
}
// else{
// self.nameLabel.shimmerColor = [UIColor clearColor];
// [self.nameLabel stopShimmer];
// }
}
-(void)previewPhotoWithCurrentIndex:(NSInteger)currentIndex{ -(void)previewPhotoWithCurrentIndex:(NSInteger)currentIndex{
NSArray *images = [self.model.home_bgimages componentsSeparatedByString:@","]; NSArray *images = [self.model.home_bgimages componentsSeparatedByString:@","];

View File

@@ -10,14 +10,14 @@
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/> <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="184" id="BqF-kO-8SX" customClass="QXExpansionCell"> <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="184" id="BqF-kO-8SX" customClass="QXExpansionCell">
<rect key="frame" x="0.0" y="0.0" width="371" height="95"/> <rect key="frame" x="0.0" y="0.0" width="375" height="95"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="BqF-kO-8SX" id="ktB-xa-Y8j"> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="BqF-kO-8SX" id="ktB-xa-Y8j">
<rect key="frame" x="0.0" y="0.0" width="371" height="95"/> <rect key="frame" x="0.0" y="0.0" width="375" height="95"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="d7u-yz-ciJ"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="d7u-yz-ciJ">
<rect key="frame" x="16" y="6" width="339" height="83"/> <rect key="frame" x="16" y="6" width="343" height="83"/>
<subviews> <subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="ij8-0l-yjh"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="ij8-0l-yjh">
<rect key="frame" x="12" y="12" width="50" height="60"/> <rect key="frame" x="12" y="12" width="50" height="60"/>
@@ -35,37 +35,18 @@
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="SRz-S8-eVY" customClass="QXSeatHeaderView"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="SRz-S8-eVY" customClass="QXSeatHeaderView">
<rect key="frame" x="12" y="12" width="50" height="60"/> <rect key="frame" x="12" y="12" width="50" height="60"/>
</view> </view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8cq-E3-DvJ"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="DJ0-UX-5S2" customClass="CKShimmerLabel">
<rect key="frame" x="93" y="20" width="40" height="18"/> <rect key="frame" x="93" y="20" width="155" height="18"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="18" id="qwD-PD-2sr"/> <constraint firstAttribute="height" constant="18" id="YBf-fM-mcV"/>
</constraints> </constraints>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/> </view>
<color key="textColor" red="0.12941176469999999" green="0.12941176469999999" blue="0.12941176469999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="gIi-P2-Y9S">
<rect key="frame" x="139" y="21" width="42" height="16"/>
<constraints>
<constraint firstAttribute="width" constant="42" id="Pa0-JD-WZI"/>
<constraint firstAttribute="height" constant="16" id="nev-GJ-TTd"/>
</constraints>
</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="SfJ-0f-fTV">
<rect key="frame" x="72" y="46" width="31.666666666666671" height="14.666666666666664"/>
<constraints>
<constraint firstAttribute="height" constant="14.67" id="ZBE-6b-COh"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/>
<color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="01B-he-W7N"> <button opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="01B-he-W7N">
<rect key="frame" x="12" y="12" width="100" height="50"/> <rect key="frame" x="12" y="12" width="100" height="50"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</button> </button>
<button opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="WzX-5h-Rjx"> <button opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="WzX-5h-Rjx">
<rect key="frame" x="254" y="29" width="73" height="26"/> <rect key="frame" x="258" y="29" width="73" height="26"/>
<constraints> <constraints>
<constraint firstAttribute="width" constant="73" id="xrz-si-tcM"/> <constraint firstAttribute="width" constant="73" id="xrz-si-tcM"/>
<constraint firstAttribute="height" constant="26" id="zly-Ov-2fX"/> <constraint firstAttribute="height" constant="26" id="zly-Ov-2fX"/>
@@ -83,7 +64,7 @@
</connections> </connections>
</button> </button>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="aff-rQ-ltL"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="aff-rQ-ltL">
<rect key="frame" x="12" y="81" width="315" height="0.0"/> <rect key="frame" x="12" y="81" width="319" height="0.0"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints> <constraints>
<constraint firstAttribute="height" id="HM6-cc-JXk"/> <constraint firstAttribute="height" id="HM6-cc-JXk"/>
@@ -96,14 +77,23 @@
<constraint firstAttribute="height" constant="16" id="txd-O6-q3p"/> <constraint firstAttribute="height" constant="16" id="txd-O6-q3p"/>
</constraints> </constraints>
</imageView> </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="SfJ-0f-fTV">
<rect key="frame" x="72" y="46" width="31.666666666666671" height="14.666666666666664"/>
<constraints>
<constraint firstAttribute="height" constant="14.67" id="ZBE-6b-COh"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/>
<color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews> </subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints> <constraints>
<constraint firstItem="DJ0-UX-5S2" firstAttribute="leading" secondItem="rE2-Ub-cG3" secondAttribute="trailing" constant="5" id="21A-eM-Lns"/>
<constraint firstItem="SRz-S8-eVY" firstAttribute="top" secondItem="ij8-0l-yjh" secondAttribute="top" id="5SH-Nr-W30"/> <constraint firstItem="SRz-S8-eVY" firstAttribute="top" secondItem="ij8-0l-yjh" secondAttribute="top" id="5SH-Nr-W30"/>
<constraint firstItem="SRz-S8-eVY" firstAttribute="leading" secondItem="ij8-0l-yjh" secondAttribute="leading" id="5xK-a1-AgP"/> <constraint firstItem="SRz-S8-eVY" firstAttribute="leading" secondItem="ij8-0l-yjh" secondAttribute="leading" id="5xK-a1-AgP"/>
<constraint firstItem="aff-rQ-ltL" firstAttribute="leading" secondItem="d7u-yz-ciJ" secondAttribute="leading" constant="12" id="7W3-i0-a7h"/> <constraint firstItem="aff-rQ-ltL" firstAttribute="leading" secondItem="d7u-yz-ciJ" secondAttribute="leading" constant="12" id="7W3-i0-a7h"/>
<constraint firstItem="ij8-0l-yjh" firstAttribute="top" secondItem="d7u-yz-ciJ" secondAttribute="top" constant="12" id="7rj-T2-7ef"/> <constraint firstItem="ij8-0l-yjh" firstAttribute="top" secondItem="d7u-yz-ciJ" secondAttribute="top" constant="12" id="7rj-T2-7ef"/>
<constraint firstItem="gIi-P2-Y9S" firstAttribute="leading" secondItem="8cq-E3-DvJ" secondAttribute="trailing" constant="6" id="9a3-JM-DNn"/>
<constraint firstItem="SfJ-0f-fTV" firstAttribute="leading" secondItem="ij8-0l-yjh" secondAttribute="trailing" constant="10" id="LpR-OW-ApF"/> <constraint firstItem="SfJ-0f-fTV" firstAttribute="leading" secondItem="ij8-0l-yjh" secondAttribute="trailing" constant="10" id="LpR-OW-ApF"/>
<constraint firstItem="SRz-S8-eVY" firstAttribute="bottom" secondItem="ij8-0l-yjh" secondAttribute="bottom" id="PL9-sW-Etp"/> <constraint firstItem="SRz-S8-eVY" firstAttribute="bottom" secondItem="ij8-0l-yjh" secondAttribute="bottom" id="PL9-sW-Etp"/>
<constraint firstAttribute="trailing" secondItem="aff-rQ-ltL" secondAttribute="trailing" constant="12" id="UJy-KH-Me6"/> <constraint firstAttribute="trailing" secondItem="aff-rQ-ltL" secondAttribute="trailing" constant="12" id="UJy-KH-Me6"/>
@@ -111,11 +101,10 @@
<constraint firstItem="rE2-Ub-cG3" firstAttribute="leading" secondItem="ij8-0l-yjh" secondAttribute="trailing" constant="10" id="Vpj-sb-ZIl"/> <constraint firstItem="rE2-Ub-cG3" firstAttribute="leading" secondItem="ij8-0l-yjh" secondAttribute="trailing" constant="10" id="Vpj-sb-ZIl"/>
<constraint firstItem="aff-rQ-ltL" firstAttribute="top" secondItem="ij8-0l-yjh" secondAttribute="bottom" constant="9" id="gpK-ex-dHB"/> <constraint firstItem="aff-rQ-ltL" firstAttribute="top" secondItem="ij8-0l-yjh" secondAttribute="bottom" constant="9" id="gpK-ex-dHB"/>
<constraint firstItem="WzX-5h-Rjx" firstAttribute="centerY" secondItem="ij8-0l-yjh" secondAttribute="centerY" id="lzk-gK-Xr5"/> <constraint firstItem="WzX-5h-Rjx" firstAttribute="centerY" secondItem="ij8-0l-yjh" secondAttribute="centerY" id="lzk-gK-Xr5"/>
<constraint firstItem="8cq-E3-DvJ" firstAttribute="centerY" secondItem="rE2-Ub-cG3" secondAttribute="centerY" id="mVr-ao-77e"/>
<constraint firstItem="SfJ-0f-fTV" firstAttribute="top" secondItem="8cq-E3-DvJ" secondAttribute="bottom" constant="8" symbolic="YES" id="pb7-FA-QT6"/>
<constraint firstItem="gIi-P2-Y9S" firstAttribute="centerY" secondItem="8cq-E3-DvJ" secondAttribute="centerY" id="qez-UP-KMH"/>
<constraint firstItem="SRz-S8-eVY" firstAttribute="trailing" secondItem="ij8-0l-yjh" secondAttribute="trailing" id="sL4-bA-4lX"/> <constraint firstItem="SRz-S8-eVY" firstAttribute="trailing" secondItem="ij8-0l-yjh" secondAttribute="trailing" id="sL4-bA-4lX"/>
<constraint firstItem="8cq-E3-DvJ" firstAttribute="leading" secondItem="rE2-Ub-cG3" secondAttribute="trailing" constant="5" id="xsB-a1-v4y"/> <constraint firstItem="DJ0-UX-5S2" firstAttribute="centerY" secondItem="rE2-Ub-cG3" secondAttribute="centerY" id="sZI-KB-uHW"/>
<constraint firstItem="SfJ-0f-fTV" firstAttribute="top" secondItem="rE2-Ub-cG3" secondAttribute="bottom" constant="9" id="t10-Md-7eL"/>
<constraint firstItem="WzX-5h-Rjx" firstAttribute="leading" secondItem="DJ0-UX-5S2" secondAttribute="trailing" constant="10" id="vCf-Pq-QOS"/>
<constraint firstAttribute="trailing" secondItem="WzX-5h-Rjx" secondAttribute="trailing" constant="12" id="yE0-Ql-MBm"/> <constraint firstAttribute="trailing" secondItem="WzX-5h-Rjx" secondAttribute="trailing" constant="12" id="yE0-Ql-MBm"/>
<constraint firstItem="ij8-0l-yjh" firstAttribute="top" secondItem="rE2-Ub-cG3" secondAttribute="bottom" constant="-25" id="yi3-el-D4c"/> <constraint firstItem="ij8-0l-yjh" firstAttribute="top" secondItem="rE2-Ub-cG3" secondAttribute="bottom" constant="-25" id="yi3-el-D4c"/>
</constraints> </constraints>
@@ -142,8 +131,7 @@
<outlet property="followBtn" destination="WzX-5h-Rjx" id="c7X-9W-ZDG"/> <outlet property="followBtn" destination="WzX-5h-Rjx" id="c7X-9W-ZDG"/>
<outlet property="imgsBgView" destination="aff-rQ-ltL" id="iQp-mS-jyp"/> <outlet property="imgsBgView" destination="aff-rQ-ltL" id="iQp-mS-jyp"/>
<outlet property="imgsBgViewHeightCon" destination="HM6-cc-JXk" id="rZb-Ea-rwx"/> <outlet property="imgsBgViewHeightCon" destination="HM6-cc-JXk" id="rZb-Ea-rwx"/>
<outlet property="levelImgV" destination="gIi-P2-Y9S" id="74c-sq-nRX"/> <outlet property="nameLabel" destination="DJ0-UX-5S2" id="f5N-Fb-M5y"/>
<outlet property="nicknameLab" destination="8cq-E3-DvJ" id="sfo-Gt-g93"/>
<outlet property="sexImageView" destination="rE2-Ub-cG3" id="zbU-Lq-BLy"/> <outlet property="sexImageView" destination="rE2-Ub-cG3" id="zbU-Lq-BLy"/>
</connections> </connections>
<point key="canvasLocation" x="216.03053435114504" y="132.04225352112678"/> <point key="canvasLocation" x="216.03053435114504" y="132.04225352112678"/>

View File

@@ -0,0 +1,22 @@
//
// QXRoomBestFriendModel.h
// QXLive
//
// Created by 启星 on 2025/11/20.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@class QXRoomBestFriendListModel,QXRoomBestFriendListSubModel;
@interface QXRoomBestFriendModel : NSObject
@property (nonatomic,strong)QXUserCpInfoModel *cp;
@property (nonatomic,strong)NSArray<QXRoomBestFriendListModel*> *no_cp;
@end
@interface QXRoomBestFriendListModel : NSObject
@property (nonatomic,strong)NSString *relation_name;
@property (nonatomic,strong)NSArray <QXRelationshipListModel*>*relation_list;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,28 @@
//
// QXRoomBestFriendModel.m
// QXLive
//
// Created by on 2025/11/20.
//
#import "QXRoomBestFriendModel.h"
@implementation QXRoomBestFriendModel
+(NSDictionary<NSString *,id> *)modelContainerPropertyGenericClass{
return @{
@"no_cp": @"QXRoomBestFriendListModel",
@"cp": @"QXUserCpInfoModel",
};
}
@end
@implementation QXRoomBestFriendListModel
+(NSDictionary<NSString *,id> *)modelContainerPropertyGenericClass{
return @{
@"relation_list": @"QXRelationshipListModel",
};
}
@end

View File

@@ -23,6 +23,11 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic,strong)NSString *room_id; @property (nonatomic,strong)NSString *room_id;
@property (nonatomic,strong)NSString *relation_name; @property (nonatomic,strong)NSString *relation_name;
@property (nonatomic,strong)NSString *end_time;
@property (nonatomic,strong)NSString *sex2;
@property (nonatomic,strong)NSString *sex1;
@property (nonatomic,strong)NSString *delete_me_coin;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@@ -44,6 +44,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic,strong)NSString *is_hide; @property (nonatomic,strong)NSString *is_hide;
/// 当前状态0-取消隐身1-隐身进入 /// 当前状态0-取消隐身1-隐身进入
@property (nonatomic,strong)NSString *hide_status; @property (nonatomic,strong)NSString *hide_status;
/// 当前状态:-1 未认证歌手, 0待审核 1已认证 2被拒绝
@property (nonatomic,strong)NSString *singer_status;
/// 各种卡片 /// 各种卡片
@property (nonatomic,strong)NSArray *icon; @property (nonatomic,strong)NSArray *icon;
/// 1 能聊天 0不能聊天 /// 1 能聊天 0不能聊天

View File

@@ -10,6 +10,7 @@
#import "QXRoomModel.h" #import "QXRoomModel.h"
#import "QXRoomFriendRelationModel.h" #import "QXRoomFriendRelationModel.h"
#import "QXRedPacketModel.h" #import "QXRedPacketModel.h"
#import "QXUserSongListModel.h"
typedef NS_ENUM(NSInteger) { typedef NS_ENUM(NSInteger) {
/// 清空消息 /// 清空消息
@@ -20,6 +21,11 @@ typedef NS_ENUM(NSInteger) {
QXRoomMessageTypeMuteRemoteAudio = 125, QXRoomMessageTypeMuteRemoteAudio = 125,
/// 关闭自己声音 /// 关闭自己声音
QXRoomMessageTypeMuteLocalAudio = 126, QXRoomMessageTypeMuteLocalAudio = 126,
/// 发送|接收到心动信号
QXRoomMessageTypeSendAndRecieveCpHeartSignal = 130,
/// cp双向奔赴
QXRoomMessageTypeCpHeartFinished = 131,
/// 基础文本消息类型 /// 基础文本消息类型
QXRoomMessageTypeText = 1, QXRoomMessageTypeText = 1,
/// 基础表情类型 /// 基础表情类型
@@ -132,6 +138,13 @@ typedef NS_ENUM(NSInteger) {
QXRoomMessageTypeSendRedpacket = 1060, QXRoomMessageTypeSendRedpacket = 1060,
/// 红包已被抢完 /// 红包已被抢完
QXRoomMessageTypeRedpacketFinished = 1061, QXRoomMessageTypeRedpacketFinished = 1061,
/// 点歌房当前歌曲发生变化
QXRoomMessageTypeSingerRoomCurrentSongDidChanged = 1070,
/// 点歌房下一首歌曲发生变化
QXRoomMessageTypeSingerRoomNextSongDidChanged = 1071,
/// 歌曲数量发生变化
QXRoomMessageTypeSingerRoomSongCountDidChanged = 1072,
}QXRoomMessageType; }QXRoomMessageType;
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@protocol QXRoomMessageManagerDelegate <NSObject> @protocol QXRoomMessageManagerDelegate <NSObject>
@@ -268,11 +281,22 @@ NS_ASSUME_NONNULL_BEGIN
/// 房间用户在线状态发生变化 /// 房间用户在线状态发生变化
//-(void)roomUserOnlineStatusDidChanged:(BOOL)isOnline userId:(NSString*)userId; //-(void)roomUserOnlineStatusDidChanged:(BOOL)isOnline userId:(NSString*)userId;
/// 点唱房当前歌曲信息发生变化
-(void)singerSongCurrentSongInfoDidChanged:(QXUserSongListModel*)model;
/// 点唱房下一首歌信息发生变化
-(void)singerSongNextSongInfoDidChanged:(QXUserSongListModel*)model;
/// 已点歌曲数量发生变化
-(void)singerSongCountDidChanged:(NSString*)count;
@end @end
@interface QXRoomMessageManager : NSObject @interface QXRoomMessageManager : NSObject
@property (nonatomic,weak)id<QXRoomMessageManagerDelegate>delegate; @property (nonatomic,weak)id<QXRoomMessageManagerDelegate>delegate;
+(instancetype)shared; +(instancetype)shared;
-(void)addC2CObserver;
/// 加入房间群组 /// 加入房间群组
-(void)joinGroupWithRoomId:(NSString*)roomId; -(void)joinGroupWithRoomId:(NSString*)roomId;
@@ -284,6 +308,8 @@ NS_ASSUME_NONNULL_BEGIN
-(void)sendChatEmoji:(QXEmojiModel *)emoji; -(void)sendChatEmoji:(QXEmojiModel *)emoji;
-(void)sendC2CMessage:(NSString *)message messageType:(QXRoomMessageType)messageType userId:(NSString*)userId; -(void)sendC2CMessage:(NSString *)message messageType:(QXRoomMessageType)messageType userId:(NSString*)userId;
-(void)showCpFinishedAlertViewWithText:(NSString*)text;
@end @end
@interface QXRoomMessage : NSObject @interface QXRoomMessage : NSObject

View File

@@ -13,6 +13,7 @@
#import <AgoraRtcKit/AgoraRtcEngineKit.h> #import <AgoraRtcKit/AgoraRtcEngineKit.h>
#import "TUIChatConfig.h" #import "TUIChatConfig.h"
#import "QXDrifNobilityJoinRoomView.h" #import "QXDrifNobilityJoinRoomView.h"
#import "QXCustomAlertView.h"
@interface QXRoomMessageManager() <V2TIMGroupListener,V2TIMSimpleMsgListener,V2TIMAdvancedMsgListener> @interface QXRoomMessageManager() <V2TIMGroupListener,V2TIMSimpleMsgListener,V2TIMAdvancedMsgListener>
@property (nonatomic,strong)NSString *groupId; @property (nonatomic,strong)NSString *groupId;
@@ -34,13 +35,15 @@
} }
return self; return self;
} }
-(void)addC2CObserver{
[[V2TIMManager sharedInstance] addSimpleMsgListener:self];
}
-(void)joinGroupWithRoomId:(NSString *)roomId{ -(void)joinGroupWithRoomId:(NSString *)roomId{
MJWeakSelf MJWeakSelf
if (self.groupId) { if (self.groupId) {
[self quitGroupWithRoomId:self.groupId]; [self quitGroupWithRoomId:self.groupId];
} }
[[V2TIMManager sharedInstance] addGroupListener:self]; [[V2TIMManager sharedInstance] addGroupListener:self];
[[V2TIMManager sharedInstance] addSimpleMsgListener:self];
[[V2TIMManager sharedInstance] addAdvancedMsgListener:self]; [[V2TIMManager sharedInstance] addAdvancedMsgListener:self];
NSString *groupId = [NSString stringWithFormat:@"room%@",roomId]; NSString *groupId = [NSString stringWithFormat:@"room%@",roomId];
[[V2TIMManager sharedInstance] joinGroup:groupId msg:@"大家好,我来啦" succ:^{ [[V2TIMManager sharedInstance] joinGroup:groupId msg:@"大家好,我来啦" succ:^{
@@ -57,7 +60,6 @@
self.groupId = nil; self.groupId = nil;
self.roomId = nil; self.roomId = nil;
[[V2TIMManager sharedInstance] removeGroupListener:self]; [[V2TIMManager sharedInstance] removeGroupListener:self];
[[V2TIMManager sharedInstance] removeSimpleMsgListener:self];
[[V2TIMManager sharedInstance] removeAdvancedMsgListener:self]; [[V2TIMManager sharedInstance] removeAdvancedMsgListener:self];
NSString *groupId = [NSString stringWithFormat:@"room%@",roomId]; NSString *groupId = [NSString stringWithFormat:@"room%@",roomId];
[[V2TIMManager sharedInstance] quitGroup:groupId succ:^{ [[V2TIMManager sharedInstance] quitGroup:groupId succ:^{
@@ -653,6 +655,28 @@
} }
} }
break; break;
case QXRoomMessageTypeSingerRoomCurrentSongDidChanged:{
QXUserSongListModel *songInfo = [QXUserSongListModel yy_modelWithJSON:msg.Text[@"song_info"]];
if (self.delegate && [self.delegate respondsToSelector:@selector(singerSongCurrentSongInfoDidChanged:)]) {
[self.delegate singerSongCurrentSongInfoDidChanged:songInfo];
}
}
break;
case QXRoomMessageTypeSingerRoomNextSongDidChanged:{
QXUserSongListModel *songInfo = [QXUserSongListModel yy_modelWithJSON:msg.Text[@"next_song_info"]];
if (self.delegate && [self.delegate respondsToSelector:@selector(singerSongNextSongInfoDidChanged:)]) {
[self.delegate singerSongNextSongInfoDidChanged:songInfo];
}
}
break;
case QXRoomMessageTypeSingerRoomSongCountDidChanged:{
NSString *songCount = [NSString stringWithFormat:@"%@",msg.Text[@"count"]];
if (self.delegate && [self.delegate respondsToSelector:@selector(singerSongCountDidChanged:)]) {
[self.delegate singerSongCountDidChanged:songCount];
}
}
break;
default: default:
break; break;
} }
@@ -672,6 +696,42 @@
*/ */
-(void)reSendGiftWithId:(NSString*)giftId userId:(NSString*)userId{
MJWeakSelf
[QXMineNetwork userCpReSendWithGiftId:giftId userId:userId roomId:self.roomId successBlock:^(NSDictionary * _Nonnull dict) {
id object = dict[@"cp_type"];
if ([object isKindOfClass:[NSDictionary class]]) {
NSDictionary *cpDict = (NSDictionary *)object;
NSString *cp_type = object[@"cp_type"];
if (cp_type.intValue == 1) {
/// cp
NSString *jsonStr = [cpDict jsonStringEncoded];
[[QXRoomMessageManager shared] sendC2CMessage:jsonStr messageType:(QXRoomMessageTypeSendAndRecieveCpHeartSignal) userId:userId];
}else if (cp_type.intValue == 2){
/// cp
NSString *jsonStr = [cpDict jsonStringEncoded];
[[QXRoomMessageManager shared] sendC2CMessage:jsonStr messageType:(QXRoomMessageTypeCpHeartFinished) userId:userId];
NSString *message = [NSString stringWithFormat:@"%@",cpDict[@"text"]];
[weakSelf showCpFinishedAlertViewWithText:message];
}else{
}
}
} failBlock:^(NSError * _Nonnull error, NSString * _Nonnull msg) {
showToast(msg);
}];
}
-(void)showCpFinishedAlertViewWithText:(NSString*)text{
QXCustomAlertView *alertView = [[QXCustomAlertView alloc] init];
[alertView showInView:KEYWINDOW title:@"缘定三生 此刻同心" message:text cancleTitle:@"稍后进入" commitTitle:@"进入心动空间"];
alertView.commitBlock = ^{
QXLOG(@"进入心动空间");
};
}
-(void)onRecvC2CTextMessage:(NSString *)msgID sender:(V2TIMUserInfo *)info text:(NSString *)text{ -(void)onRecvC2CTextMessage:(NSString *)msgID sender:(V2TIMUserInfo *)info text:(NSString *)text{
@@ -688,6 +748,23 @@
if (self.delegate && [self.delegate respondsToSelector:@selector(pkMuteRemoteAudio:fromUserInfo:)]) { if (self.delegate && [self.delegate respondsToSelector:@selector(pkMuteRemoteAudio:fromUserInfo:)]) {
[self.delegate pkMuteRemoteAudio:is_mute==1 fromUserInfo:model.FromUserInfo]; [self.delegate pkMuteRemoteAudio:is_mute==1 fromUserInfo:model.FromUserInfo];
} }
}else if (meesageType == QXRoomMessageTypeSendAndRecieveCpHeartSignal){
NSString *json = [NSString stringWithFormat:@"%@",msg.Text[@"text"]];
NSDictionary *dict = [json jsonValueDecoded];
NSString *message = [NSString stringWithFormat:@"%@",dict[@"text1"]];
__block NSString *gift_id = [NSString stringWithFormat:@"%@",dict[@"gift_id"]];
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
QXCustomAlertView *alertView = [[QXCustomAlertView alloc] init];
[alertView showInView:KEYWINDOW title:@"心动信号" message:message cancleTitle:@"再想想" commitTitle:@"回赠"];
MJWeakSelf
alertView.commitBlock = ^{
[weakSelf reSendGiftWithId:gift_id userId:model.FromUserInfo.user_id];
};
}else if (meesageType == QXRoomMessageTypeCpHeartFinished){
NSString *json = [NSString stringWithFormat:@"%@",msg.Text[@"text"]];
NSDictionary *dict = [json jsonValueDecoded];
NSString *message = [NSString stringWithFormat:@"%@",dict[@"text1"]];
[self showCpFinishedAlertViewWithText:message];
} }
} }
-(void)onRecvGroupCustomMessage:(NSString *)msgID groupID:(NSString *)groupID sender:(V2TIMGroupMemberInfo *)info customData:(NSData *)data{ -(void)onRecvGroupCustomMessage:(NSString *)msgID groupID:(NSString *)groupID sender:(V2TIMGroupMemberInfo *)info customData:(NSData *)data{
@@ -719,7 +796,7 @@
}else if (meesageType == QXRoomMessageTypeMuteLocalAudio){ }else if (meesageType == QXRoomMessageTypeMuteLocalAudio){
NSString *json = [NSString stringWithFormat:@"%@",msg.Text[@"text"]]; NSString *json = [NSString stringWithFormat:@"%@",msg.Text[@"text"]];
NSDictionary *dict = [json jsonValueDecoded]; NSDictionary *dict = [json jsonValueDecoded];
NSInteger is_mute = [[dict objectForKey:@"is_mute"] integerValue]; // NSInteger is_mute = [[dict objectForKey:@"is_mute"] integerValue];
QXUserHomeModel *userModel = [QXUserHomeModel yy_modelWithJSON:msg.Text[@"FromUserInfo"]]; QXUserHomeModel *userModel = [QXUserHomeModel yy_modelWithJSON:msg.Text[@"FromUserInfo"]];
AgoraRtcAudioVolumeInfo *userInfo = [[AgoraRtcAudioVolumeInfo alloc] init]; AgoraRtcAudioVolumeInfo *userInfo = [[AgoraRtcAudioVolumeInfo alloc] init];
userInfo.uid = userModel.user_id.longLongValue; userInfo.uid = userModel.user_id.longLongValue;
@@ -855,9 +932,9 @@
[[V2TIMManager sharedInstance] sendMessage:message1 receiver:toUserId groupID:nil priority:(V2TIM_PRIORITY_HIGH) onlineUserOnly:YES offlinePushInfo:nil progress:^(uint32_t progress) { [[V2TIMManager sharedInstance] sendMessage:message1 receiver:toUserId groupID:nil priority:(V2TIM_PRIORITY_HIGH) onlineUserOnly:YES offlinePushInfo:nil progress:^(uint32_t progress) {
} succ:^{ } succ:^{
QXLOG(@"c2c发送成功");
} fail:^(int code, NSString * _Nullable desc) { } fail:^(int code, NSString * _Nullable desc) {
QXLOG(@"c2c发送失败");
}]; }];
} }
@end @end

View File

@@ -33,6 +33,9 @@
#import "QXGiftWallViewController.h" #import "QXGiftWallViewController.h"
#import "QXNobilityViewController.h" #import "QXNobilityViewController.h"
#import "QXHomePageNetwork.h" #import "QXHomePageNetwork.h"
#import "QXRoomSingerAuthViewController.h"
#import "QXMineSongListViewController.h"
#import "QXIntimateViewController.h"
#import <WXApi.h> #import <WXApi.h>
@interface QXMineViewController ()<UITableViewDelegate,UITableViewDataSource,QXMineServiceCellDelegate,QXMainHeaderViewDelegate> @interface QXMineViewController ()<UITableViewDelegate,UITableViewDataSource,QXMineServiceCellDelegate,QXMainHeaderViewDelegate>
@@ -148,6 +151,19 @@
[WXApi sendReq:req completion:nil]; [WXApi sendReq:req completion:nil];
} }
break; break;
case QXMineServiceTypeSingerAuth:{
QXLOG(@"点击了歌手认证");
QXRoomSingerAuthViewController *vc = [[QXRoomSingerAuthViewController alloc] init];
vc.singer_status = self.userModel.singer_status;
[self.navigationController pushViewController:vc animated:YES];
}
break;
case QXMineServiceTypeSongList:{
QXLOG(@"我的歌单");
QXMineSongListViewController *vc = [[QXMineSongListViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
}
break;
default: default:
break; break;
} }
@@ -195,7 +211,9 @@
break; break;
case QXMainHeaderOptionTypeFriend:{ case QXMainHeaderOptionTypeFriend:{
QXLOG(@"跳转挚友"); QXLOG(@"跳转挚友");
QXIntimateViewController *vc = [[QXIntimateViewController alloc] init];
vc.userId = QXGlobal.shareGlobal.loginModel.user_id;
[self.navigationController pushViewController:vc animated:YES];
} }
break; break;
case QXMainHeaderOptionTypeGiftWall:{ case QXMainHeaderOptionTypeGiftWall:{
@@ -288,11 +306,11 @@
if (indexPath.row == 0) { if (indexPath.row == 0) {
return ScaleWidth(110); return ScaleWidth(110);
}else{ }else{
if (QXGlobal.shareGlobal.isOpenRecharge) { // if (QXGlobal.shareGlobal.isOpenRecharge) {
return ScaleWidth(168); return ScaleWidth(168);
}else{ // }else{
return ScaleWidth(110); // return ScaleWidth(110);
} // }
} }
} }
-(void)getBanner{ -(void)getBanner{

View File

@@ -16,6 +16,8 @@
#import "QXCreatPhotosViewController.h" #import "QXCreatPhotosViewController.h"
#import "QXMineNetwork.h" #import "QXMineNetwork.h"
#import "QXPhotosDetailVC.h" #import "QXPhotosDetailVC.h"
#import "QXIntimateContentView.h"
#import "QXHeartBeatSpaceViewController.h"
@interface QXUserHomePageViewController ()<JXCategoryViewDelegate,JXPagerViewDelegate,SDCycleScrollViewDelegate> @interface QXUserHomePageViewController ()<JXCategoryViewDelegate,JXPagerViewDelegate,SDCycleScrollViewDelegate>
@property (nonatomic,strong)UIImageView * backgourdImageView; @property (nonatomic,strong)UIImageView * backgourdImageView;
@@ -27,6 +29,7 @@
@property (nonatomic, strong) JXCategoryTitleView *categoryView; @property (nonatomic, strong) JXCategoryTitleView *categoryView;
@property (nonatomic, strong) NSArray <NSString *> *titles; @property (nonatomic, strong) NSArray <NSString *> *titles;
@property (nonatomic, assign)CGRect cycleScrollViewFrame; @property (nonatomic, assign)CGRect cycleScrollViewFrame;
@property (nonatomic, strong)QXUserHomeModel *userModel;
@end @end
@implementation QXUserHomePageViewController @implementation QXUserHomePageViewController
@@ -44,6 +47,8 @@
self.navigationController.navigationBar.backgroundColor = [UIColor clearColor]; self.navigationController.navigationBar.backgroundColor = [UIColor clearColor];
} }
- (void)initSubViews{ - (void)initSubViews{
self.bgImageHidden = YES;
self.view.backgroundColor = RGB16(0xF3F3F3);
self.cycleScrollView = [SDCycleScrollView cycleScrollViewWithFrame:CGRectMake(0, 0, self.view.width, 121+NavContentHeight+16) delegate:self placeholderImage:[UIImage imageNamed:@"user_header_placehoulder"]]; self.cycleScrollView = [SDCycleScrollView cycleScrollViewWithFrame:CGRectMake(0, 0, self.view.width, 121+NavContentHeight+16) delegate:self placeholderImage:[UIImage imageNamed:@"user_header_placehoulder"]];
self.cycleScrollView.bannerImageViewContentMode = UIViewContentModeScaleAspectFill; self.cycleScrollView.bannerImageViewContentMode = UIViewContentModeScaleAspectFill;
@@ -57,7 +62,7 @@
self.cycleScrollViewFrame = self.backgourdImageView.frame; self.cycleScrollViewFrame = self.backgourdImageView.frame;
[self.view addSubview:self.backgourdImageView]; [self.view addSubview:self.backgourdImageView];
self.titles = @[QXText(@"动态"),QXText(@"礼物墙"),QXText(@"我的相册")]; self.titles = @[QXText(@"动态"),QXText(@"挚友"),QXText(@"我的相册")];
_categoryView = [[JXCategoryTitleView alloc] init]; _categoryView = [[JXCategoryTitleView alloc] init];
self.categoryView.frame = CGRectMake(0, 0, 200, 48); self.categoryView.frame = CGRectMake(0, 0, 200, 48);
self.categoryView.titles = self.titles; self.categoryView.titles = self.titles;
@@ -106,7 +111,15 @@
-(void)getUserInfo{ -(void)getUserInfo{
MJWeakSelf MJWeakSelf
[QXMineNetwork userHomePageWithUserId:self.user_id successBlock:^(QXUserHomeModel * _Nonnull userModel) { [QXMineNetwork userHomePageWithUserId:self.user_id successBlock:^(QXUserHomeModel * _Nonnull userModel) {
weakSelf.userModel = userModel;
weakSelf.headerView.hidden = NO;
weakSelf.headerView.model = userModel; weakSelf.headerView.model = userModel;
if (weakSelf.userModel.cp_info != nil) {
weakSelf.headerView.height = 243+ScaleWidth(40)+8+ScaleWidth(100)+14;
}else{
weakSelf.headerView.height = 243+ScaleWidth(40)+8;
}
[weakSelf.pagingView resizeTableHeaderViewHeightWithAnimatable:NO duration:0.1 curve:UIViewAnimationCurveLinear];
NSArray *imgs; NSArray *imgs;
if (userModel.home_bgimages.length > 0) { if (userModel.home_bgimages.length > 0) {
imgs = [userModel.home_bgimages componentsSeparatedByString:@","]; imgs = [userModel.home_bgimages componentsSeparatedByString:@","];
@@ -134,7 +147,7 @@
return self.headerView; return self.headerView;
} }
- (NSUInteger)tableHeaderViewHeightInPagerView:(JXPagerView *)pagerView { - (NSUInteger)tableHeaderViewHeightInPagerView:(JXPagerView *)pagerView {
return 215+26; return self.headerView.height;
} }
- (NSUInteger)heightForPinSectionHeaderInPagerView:(JXPagerView *)pagerView { - (NSUInteger)heightForPinSectionHeaderInPagerView:(JXPagerView *)pagerView {
@@ -155,10 +168,13 @@
dynamicView.backgroundColor = RGB16(0xf6f6f6); dynamicView.backgroundColor = RGB16(0xf6f6f6);
return dynamicView; return dynamicView;
}else if(index == 1){ }else if(index == 1){
QXUserGiftWallView *giftWallView = [[QXUserGiftWallView alloc] init]; // QXUserGiftWallView *giftWallView = [[QXUserGiftWallView alloc] init];
giftWallView.backgroundColor = RGB16(0xf6f6f6); // giftWallView.backgroundColor = RGB16(0xf6f6f6);
giftWallView.user_id = self.user_id; // giftWallView.user_id = self.user_id;
return giftWallView; // return giftWallView;
QXIntimateContentView *intimateView = [[QXIntimateContentView alloc] init];
intimateView.userId = self.user_id;
return intimateView;
}else{ }else{
QXUserPhotosView *photosView = [[QXUserPhotosView alloc] init]; QXUserPhotosView *photosView = [[QXUserPhotosView alloc] init];
photosView.user_id = self.user_id; photosView.user_id = self.user_id;
@@ -179,6 +195,8 @@
-(QXUserHomeHeaderView *)headerView{ -(QXUserHomeHeaderView *)headerView{
if (!_headerView) { if (!_headerView) {
_headerView = [[QXUserHomeHeaderView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 215+26)]; _headerView = [[QXUserHomeHeaderView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 215+26)];
_headerView.userId = self.user_id;
_headerView.hidden = YES;
} }
return _headerView; return _headerView;
} }

View File

@@ -0,0 +1,16 @@
//
// QXHeartBeatSpaceViewController.h
// QXLive
//
// Created by 启星 on 2025/11/21.
//
#import "QXBaseViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface QXHeartBeatSpaceViewController : QXBaseViewController
@property (nonatomic,strong)NSString *userId;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,22 @@
//
// QXHeartBeatSpaceViewController.m
// QXLive
//
// Created by on 2025/11/21.
//
#import "QXHeartBeatSpaceViewController.h"
@interface QXHeartBeatSpaceViewController ()
@end
@implementation QXHeartBeatSpaceViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
@end

View File

@@ -0,0 +1,16 @@
//
// QXIntimateViewController.h
// QXLive
//
// Created by 启星 on 2025/11/20.
//
#import "QXBaseViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface QXIntimateViewController : QXBaseViewController
@property (nonatomic,strong)NSString *userId;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,242 @@
//
// QXIntimateViewController.m
// QXLive
//
// Created by on 2025/11/20.
//
#import "QXIntimateViewController.h"
#import "QXIntimateCpCell.h"
#import "QXIntimateListCell.h"
#import "QXIntimateNoCpCell.h"
#import "QXMineNetwork.h"
#import "QXButton.h"
#import "QXMoreIntimateViewController.h"
#import "QXIntimateMoreListCell.h"
#import "QXHeartBeatSpaceViewController.h"
@interface QXIntimateViewController ()<UITableViewDataSource,UITableViewDelegate>
@property (nonatomic,strong)UITableView *tableView;
@property (nonatomic,strong)QXRoomBestFriendModel *model;
@end
@implementation QXIntimateViewController
- (void)viewDidLoad {
self.isNoChangeBgImage = YES;
[super viewDidLoad];
// Do any additional setup after loading the view.
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
-(void)setNavgationItems{
[super setNavgationItems];
}
- (void)initSubViews{
self.page = 1;
[self updateBgImage:@"mine_intimate_bg"];
[self updateBackImage:[UIImage imageNamed:@"mine_intimate_back"]];
UIImageView *titleImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"mine_intimate_title_img"]];
[self.view addSubview:titleImageView];
[titleImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.view);
make.width.mas_equalTo(ScaleWidth(178));
make.height.mas_equalTo(ScaleWidth(68));
make.top.mas_equalTo(NavContentHeight);
}];
[self.view addSubview:self.tableView];
}
-(void)setUserId:(NSString *)userId{
_userId = userId;
self.page = 1;
[self getList];
}
-(void)getList{
MJWeakSelf
[QXMineNetwork userBestFriendsListWithUserId:self.userId page:self.page successBlock:^(QXRoomBestFriendModel * _Nonnull model) {
weakSelf.model = model;
if (weakSelf.page == 1) {
[weakSelf.dataArray removeAllObjects];
}
[weakSelf.dataArray addObjectsFromArray:model.no_cp];
[weakSelf.tableView reloadData];
if (model.no_cp.count == 0) {
weakSelf.tableView.mj_footer.state = MJRefreshStateNoMoreData;
}else{
[weakSelf.tableView.mj_footer endRefreshing];
}
[weakSelf.tableView.mj_header endRefreshing];
} failBlock:^(NSError * _Nonnull error, NSString * _Nonnull msg) {
}];
}
-(void)moreAction:(QXButton*)btn{
QXRoomBestFriendListModel *md = btn.object;
QXMoreIntimateViewController *vc = [[QXMoreIntimateViewController alloc] init];
vc.userId = self.userId;
vc.relation_id = md.relation_list.firstObject.relation_id;
[self.navigationController pushViewController:vc animated:YES];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
if (self.model == nil) {
return 0;
}else{
return 1+self.dataArray.count;
}
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 1;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.section == 0) {
if (self.model.cp) {
QXIntimateCpCell *cell = [QXIntimateCpCell cellWithTableView:tableView];
cell.model = self.model.cp;
return cell;
}else{
QXIntimateNoCpCell *cell = [QXIntimateNoCpCell cellWithTableView:tableView];
return cell;
}
}else{
QXRoomBestFriendListModel *md = self.dataArray[indexPath.section-1];
if (md.relation_list.count > 1) {
QXIntimateListCell*cell = [QXIntimateListCell cellWithTableView:tableView];
if (self.dataArray.count>0) {
QXRoomBestFriendListModel *md = self.dataArray[indexPath.section-1];
cell.model = md;
}
return cell;
}else{
MJWeakSelf
QXIntimateMoreListCell *cell = [QXIntimateMoreListCell cellWithTableView:tableView];
QXRoomBestFriendListModel *md = self.dataArray.firstObject;
cell.model = md.relation_list.firstObject;
cell.deleteSuccessBlock = ^(QXRelationshipListModel * _Nonnull model) {
weakSelf.page = 1;
[weakSelf getList];
};
return cell;
}
}
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.width, 50)];
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"mine_intimate_title_bg"]];
UILabel *titleLabel = [[UILabel alloc] init];
titleLabel.font = [UIFont boldSystemFontOfSize:16];
titleLabel.textColor = RGB16(0xffffff);
QXButton *btn = [[QXButton alloc] init];
[btn setTitle:@"更多>>" forState:(UIControlStateNormal)];
[btn setTitleColor:RGB16(0xE973FC) forState:(UIControlStateNormal)];
btn.titleLabel.font = [UIFont systemFontOfSize:12];
[btn addTarget:self action:@selector(moreAction:) forControlEvents:(UIControlEventTouchUpInside)];
[header addSubview:btn];
[header addSubview:imageView];
[header addSubview:titleLabel];
[imageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.mas_equalTo(132);
make.height.mas_equalTo(36);
make.centerX.centerY.equalTo(header);
}];
[titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(header);
make.centerY.equalTo(header).offset(2);
}];
[btn mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.mas_equalTo(-23);
make.top.bottom.equalTo(header);
make.width.mas_equalTo(40);
}];
if (section == 0) {
titleLabel.text = @"心动";
btn.hidden = YES;
}else{
QXRoomBestFriendListModel *md = self.dataArray[section-1];
titleLabel.text = md.relation_name;
if (md.relation_list.count>1) {
btn.hidden = NO;
btn.object = md;
}else{
btn.hidden = YES;
}
}
return header;
}
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
return 50;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.section == 0) {
if (self.model.cp) {
return ScaleWidth(100);
}else{
return ScaleWidth(36);
}
}else{
QXRoomBestFriendListModel *md = self.dataArray[indexPath.section-1];
if (md.relation_list.count > 1) {
return ScaleWidth(92)+18;
}else{
if (md.relation_list.count == 0) {
return 0;
}else{
return ScaleWidth(100)+16;
}
}
}
}
-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{
UIView *footer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.width, 15)];
return footer;
}
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
return 15;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.section == 0) {
if (self.model.cp) {
QXHeartBeatSpaceViewController *vc = [[QXHeartBeatSpaceViewController alloc] init];
vc.userId = self.userId;
[self.navigationController pushViewController:vc animated:YES];
}
}
}
-(UITableView *)tableView{
if (!_tableView) {
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, NavContentHeight+ScaleWidth(68), SCREEN_WIDTH, SCREEN_HEIGHT -NavContentHeight-ScaleWidth(68)) style:(UITableViewStyleGrouped)];
_tableView.dataSource = self;
_tableView.delegate = self;
_tableView.backgroundColor = [UIColor clearColor];
_tableView.tableFooterView = [UIView new];
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
if (@available(iOS 15.0, *)) {
_tableView.sectionHeaderTopPadding = 0;
} else {
// Fallback on earlier versions
}
MJWeakSelf
_tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
weakSelf.page = 1;
[weakSelf getList];
}];
_tableView.mj_footer = [MJRefreshBackNormalFooter footerWithRefreshingBlock:^{
weakSelf.page++;
[weakSelf getList];
}];
}
return _tableView;
}
@end

View File

@@ -0,0 +1,17 @@
//
// QXMoreIntimateViewController.h
// QXLive
//
// Created by 启星 on 2025/11/20.
//
#import "QXBaseViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface QXMoreIntimateViewController : QXBaseViewController
@property (nonatomic,strong)NSString *userId;
@property (nonatomic,strong)NSString *relation_id;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,76 @@
//
// QXMoreIntimateViewController.m
// QXLive
//
// Created by on 2025/11/20.
//
#import "QXMoreIntimateViewController.h"
#import "QXMineNetwork.h"
#import "QXIntimateMoreListCell.h"
@interface QXMoreIntimateViewController ()<UITableViewDataSource,UITableViewDelegate>
@property (nonatomic,strong)UITableView *tableView;
@end
@implementation QXMoreIntimateViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
-(void)setUserId:(NSString *)userId{
_userId = userId;
}
-(void)setRelation_id:(NSString *)relation_id{
_relation_id = relation_id;
if (self.userId) {
[self getList];
}
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.dataArray.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
QXIntimateMoreListCell *cell = [QXIntimateMoreListCell cellWithTableView:tableView];
cell.model = self.dataArray[indexPath.row];
MJWeakSelf
cell.topSuccessBlock = ^(QXRelationshipListModel * _Nonnull model) {
[weakSelf getList];
};
cell.deleteSuccessBlock = ^(QXRelationshipListModel * _Nonnull model) {
[weakSelf getList];
};
return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return ScaleWidth(92)+16;
}
-(void)getList{
MJWeakSelf
[QXMineNetwork userBestFriendsMoreListWithUserId:self.userId relation_id:self.relation_id successBlock:^(NSArray<QXRelationshipListModel *> * _Nonnull model) {
[weakSelf.dataArray removeAllObjects];
[weakSelf.dataArray addObjectsFromArray:model];
[weakSelf.tableView reloadData];
} failBlock:^(NSError * _Nonnull error, NSString * _Nonnull msg) {
}];
}
-(UITableView *)tableView{
if (!_tableView) {
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, NavContentHeight+ScaleWidth(68), SCREEN_WIDTH, SCREEN_HEIGHT -NavContentHeight-ScaleWidth(68)) style:(UITableViewStyleGrouped)];
_tableView.dataSource = self;
_tableView.delegate = self;
_tableView.backgroundColor = [UIColor clearColor];
_tableView.tableFooterView = [UIView new];
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
if (@available(iOS 15.0, *)) {
_tableView.sectionHeaderTopPadding = 0;
} else {
// Fallback on earlier versions
}
}
return _tableView;
}
@end

View File

@@ -0,0 +1,16 @@
//
// QXMineSongListViewController.h
// QXLive
//
// Created by 启星 on 2025/11/13.
//
#import "QXBaseViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface QXMineSongListViewController : QXBaseViewController
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,196 @@
//
// QXMineSongListViewController.m
// QXLive
//
// Created by on 2025/11/13.
//
#import "QXMineSongListViewController.h"
#import "QXMineNetwork.h"
#import "QXMineSongListCell.h"
#import "QXMineAddSongView.h"
#import "QXMineAddSongGiftView.h"
#import "QXCustomAlertView.h"
@interface QXMineSongListViewController ()<UITableViewDataSource,UITableViewDelegate,QXMineAddSongViewDelegate,QXMineAddSongGiftViewDelegate>
@property (nonatomic,strong)UITableView *tableView;
@property (nonatomic,strong)UILabel *countLabel;
@property (nonatomic,strong)QXMineAddSongView *addSongView;
@end
@implementation QXMineSongListViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
}
-(void)setNavgationItems{
[super setNavgationItems];;
self.navigationItem.title = @"歌单列表";
UIButton*recordBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 44, 44)];
[recordBtn setTitle:QXText(@"新增") forState:(UIControlStateNormal)];
[recordBtn setTitleColor:QXConfig.themeColor forState:(UIControlStateNormal)];
recordBtn.titleLabel.font = [UIFont systemFontOfSize:16];
[recordBtn addTarget:self action:@selector(addAction) forControlEvents:(UIControlEventTouchUpInside)];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:recordBtn];
}
-(void)initSubViews{
self.page = 1;
self.countLabel = [[UILabel alloc] initWithFrame:CGRectMake(16, NavContentHeight+12, 200, 17)];
self.countLabel.textColor = RGB16A(0x000000,0.45);
self.countLabel.font = [UIFont systemFontOfSize:12];
self.countLabel.text = @"共0首歌";
[self.view addSubview:self.countLabel];
[self.view addSubview:self.tableView];
[self getSongList];
}
-(void)getSongList{
MJWeakSelf
[QXMineNetwork getUserSongListWithRoomId:@"" user_id:QXGlobal.shareGlobal.loginModel.user_id page:self.page SuccessBlock:^(NSArray<QXUserSongListModel *> * _Nonnull list, NSString * _Nonnull count) {
weakSelf.countLabel.text = [NSString stringWithFormat:@"共有%@首歌",count];
if (weakSelf.page == 1) {
[weakSelf.dataArray removeAllObjects];
}
[weakSelf.dataArray addObjectsFromArray:list];
[weakSelf.tableView reloadData];
[weakSelf.tableView.mj_header endRefreshing];
if (list.count == 0) {
weakSelf.tableView.mj_footer.state = MJRefreshStateNoMoreData;
}else{
[weakSelf.tableView.mj_header endRefreshing];
}
} failBlock:^(NSError * _Nonnull error, NSString * _Nonnull msg) {
}];
}
-(void)didSeletedGift:(QXGiftModel *)giftModel giftCount:(nonnull NSString *)giftCount{
giftModel.num = giftCount;
self.addSongView.giftModel = giftModel;
}
-(void)qx_mineAddSongViewDidSeleteGift{
QXMineAddSongGiftView *giftView = [[QXMineAddSongGiftView alloc] initWithFrame:[UIScreen mainScreen].bounds];
giftView.delegate = self;
[giftView showInView:self.view];
}
-(void)qx_mineAddSongViewCommitWithSongName:(NSString *)songName giftModel:(QXGiftModel *)giftModel{
MJWeakSelf
[QXMineNetwork mineUserAddAndDeleteAndEditWithType:0 Id:@"" songName:songName giftId:giftModel.gift_id giftNum:giftModel.num successBlock:^(NSDictionary * _Nonnull dict) {
showToast(@"添加成功");
[weakSelf.addSongView hide];
weakSelf.page = 1;
[weakSelf getSongList];
} failBlock:^(NSError * _Nonnull error, NSString * _Nonnull msg) {
showToast(@"添加失败");
}];
}
-(void)qx_mineAddSongViewDidRemove{
self.addSongView = nil;
}
-(void)qx_mineEditSongViewCommitWithSongModel:(QXUserSongListModel *)songModel{
MJWeakSelf
[QXMineNetwork mineUserAddAndDeleteAndEditWithType:1 Id:songModel.id songName:songModel.song_name giftId:songModel.gift_id giftNum:songModel.gift_num successBlock:^(NSDictionary * _Nonnull dict) {
showToast(@"修改成功");
[weakSelf.addSongView hide];
weakSelf.page = 1;
[weakSelf getSongList];
} failBlock:^(NSError * _Nonnull error, NSString * _Nonnull msg) {
showToast(@"修改失败");
}];
}
-(void)addAction{
self.addSongView = [[QXMineAddSongView alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.addSongView.delegate = self;
[self.addSongView showInView:self.view];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.dataArray.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
QXMineSongListCell *cell = [QXMineSongListCell cellWithTableView:tableView];
cell.model = self.dataArray[indexPath.row];
return cell;
}
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
return YES;
}
-(UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath{
QXUserSongListModel *model = self.dataArray[indexPath.row];
MJWeakSelf
UIContextualAction *deletAction = [UIContextualAction contextualActionWithStyle:(UIContextualActionStyleDestructive) title:@"删除" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
[weakSelf deleteSongWithModel:model];
completionHandler(YES);
}];
UIContextualAction *editAction = [UIContextualAction contextualActionWithStyle:(UIContextualActionStyleNormal) title:@"编辑" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
[weakSelf editSongWithModel:model];
completionHandler(YES);
}];
editAction.backgroundColor = RGB16(0x3665F9);
UISwipeActionsConfiguration *config = [UISwipeActionsConfiguration configurationWithActions:@[deletAction,editAction]];
return config;
}
-(void)deleteSongWithModel:(QXUserSongListModel*)model{
QXCustomAlertView *alertView = [[QXCustomAlertView alloc] init];
[alertView showInView:self.view title:@"您确定要删除歌曲吗" message:[NSString stringWithFormat:@"歌曲名称:%@\n礼物信息%@ x%@",model.song_name,model.gift_name,model.gift_num] cancleTitle:@"取消" commitTitle:@"确定"];
MJWeakSelf
alertView.commitBlock = ^{
[QXMineNetwork mineUserAddAndDeleteAndEditWithType:2 Id:model.id songName:model.song_name giftId:model.gift_id giftNum:model.gift_num successBlock:^(NSDictionary * _Nonnull dict) {
showToast(@"删除成功");
weakSelf.page = 1;
[weakSelf getSongList];
} failBlock:^(NSError * _Nonnull error, NSString * _Nonnull msg) {
showToast(@"删除失败");
}];
};
}
-(void)editSongWithModel:(QXUserSongListModel*)model{
self.addSongView = [[QXMineAddSongView alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.addSongView.delegate = self;
self.addSongView.songModel = model;
[self.addSongView showInView:self.view];
}
-(UITableView *)tableView{
if (!_tableView) {
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(16, self.countLabel.bottom+5, SCREEN_WIDTH-32, SCREEN_HEIGHT-NavContentHeight) style:(UITableViewStylePlain)];
_tableView.dataSource = self;
_tableView.delegate = self;
_tableView.backgroundColor = [UIColor whiteColor];
[_tableView addRoundedCornersWithRadius:16 byRoundingCorners:(UIRectCornerTopLeft|UIRectCornerTopRight)];
_tableView.rowHeight = 45;
// _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
if (@available(iOS 15.0, *)) {
_tableView.sectionHeaderTopPadding = 0;
} else {
// Fallback on earlier versions
}
MJWeakSelf
_tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
weakSelf.page = 1;
[weakSelf getSongList];
}];
_tableView.mj_footer = [MJRefreshBackNormalFooter footerWithRefreshingBlock:^{
weakSelf.page++;
[weakSelf getSongList];
}];
}
return _tableView;
}
@end

View File

@@ -0,0 +1,17 @@
//
// QXRoomSingerAuthViewController.h
// QXLive
//
// Created by 启星 on 2025/11/12.
//
#import "QXBaseViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface QXRoomSingerAuthViewController : QXBaseViewController
/// 当前状态:-1 未认证歌手, 0待审核 1已认证 2被拒绝
@property (nonatomic,strong)NSString *singer_status;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,116 @@
//
// QXRoomSingerAuthViewController.m
// QXLive
//
// Created by on 2025/11/12.
//
#import "QXRoomSingerAuthViewController.h"
#import "QXAudioRecorderView.h"
@interface QXRoomSingerAuthViewController ()<QXAudioRecorderViewDelegate>
@property (nonatomic,strong)UIView *contentView;
@property (nonatomic,strong)UIImageView *contentImageView;
@property (nonatomic,strong)UIImageView *myAuthImageView;
@property (nonatomic,strong)UIImageView *authStatusImageView;
@property (nonatomic,strong)UILabel *authStatusLabel;
@property (nonatomic,strong)QXAudioRecorderView *audioRecorderView;
@end
@implementation QXRoomSingerAuthViewController
- (void)viewDidLoad {
self.isNoChangeBgImage = YES;
[super viewDidLoad];
// Do any additional setup after loading the view.
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:NO animated:YES];
self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName:RGB16(0xffffff)};
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName:RGB16(0x000000)};
}
-(void)setNavgationItems{
[super setNavgationItems];
self.navigationTintColor = RGB16(0xffffff);
self.navigationItem.title = @"歌手认证";
}
- (void)initSubViews{
[self updateBgImage:@"singer_auth_bg"];
self.contentView = [[UIView alloc] initWithFrame:CGRectMake(16, ScaleWidth(300), SCREEN_WIDTH-32, ScaleWidth(140))];
[self.view addSubview:self.contentView];
self.contentImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"singer_auth_center_bg"]];
self.contentImageView.contentMode = UIViewContentModeScaleToFill;
self.contentImageView.frame = self.contentView.bounds;
[self.contentView addSubview:self.contentImageView];
self.myAuthImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"singer_auth_title_image"]];
self.myAuthImageView.frame = CGRectMake((self.contentView.width-ScaleWidth(69))/2, ScaleWidth(10), ScaleWidth(69), ScaleWidth(24));
[self.contentView addSubview:self.myAuthImageView];
self.authStatusImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"singer_auth_status_no"]];
self.authStatusImageView.frame = CGRectMake((self.contentView.width-ScaleWidth(52))/2, self.myAuthImageView.bottom+ScaleWidth(22), ScaleWidth(52), ScaleWidth(52));
[self.contentView addSubview:self.authStatusImageView];
self.authStatusLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, self.authStatusImageView.bottom+4, self.contentView.width, 17)];
self.authStatusLabel.text = @"暂未认证";
self.authStatusLabel.textColor = RGB16A(0x000000, 0.45);
self.authStatusLabel.font = [UIFont systemFontOfSize:12];
self.authStatusLabel.textAlignment = NSTextAlignmentCenter;
[self.contentView addSubview:self.authStatusLabel];
self.audioRecorderView = [[QXAudioRecorderView alloc] initWithFrame:CGRectMake(0, SCREEN_HEIGHT-kSafeAreaBottom-246, SCREEN_WIDTH, 246+kSafeAreaBottom) maxDuration:300];
self.audioRecorderView.delegate = self;
self.audioRecorderView.hidden = YES;
[self.view addSubview:self.audioRecorderView];
if ([self.singer_status isEqualToString:@"-1"] || [self.singer_status isEqualToString:@"2"]) {
self.audioRecorderView.hidden = NO;
}
if ([self.singer_status isEqualToString:@"-1"]) {
self.authStatusLabel.text = @"暂未认证";
self.authStatusLabel.textColor = RGB16A(0x000000, 0.45);
}else if ([self.singer_status isEqualToString:@"0"]) {
self.authStatusLabel.text = @"待审核";
self.authStatusLabel.textColor = RGB16(0xFF8832);
}else if ([self.singer_status isEqualToString:@"1"]) {
self.authStatusLabel.text = @"已认证";
self.authStatusLabel.textColor = QXConfig.themeColor;
}else if ([self.singer_status isEqualToString:@"2"]) {
self.authStatusLabel.text = @"已拒绝";
self.authStatusLabel.textColor = RGB16(0xFF2424);
}
}
#pragma mark - AudioRecorderViewDelegate
- (void)qxAudioRecorderView:(QXAudioRecorderView *)recorderView didChangeState:(AudioRecorderState)state{
NSLog(@"录音状态改变: %ld", (long)state);
}
- (void)qxAudioRecorderView:(QXAudioRecorderView *)recorderView didFinishRecordingWithMP3File:(NSURL *)mp3FileURL duration:(NSTimeInterval)duration{
NSLog(@"录音完成MP3文件: %@, 总时长: %.1f秒", mp3FileURL, duration);
//
NSData *audioData = [NSData dataWithContentsOfURL:mp3FileURL];
NSLog(@"MP3文件大小: %.2f KB", audioData.length / 1024.0);
}
- (void)qxAudioRecorderView:(QXAudioRecorderView *)recorderView didFailWithError:(NSError *)error{
NSLog(@"录音失败: %@", error);
}
- (void)qxAudioRecorderView:(QXAudioRecorderView *)recorderView didUpdateProgress:(NSTimeInterval)progress totalDuration:(NSTimeInterval)totalDuration{
//
}
@end

View File

@@ -157,6 +157,19 @@
[self setPirce]; [self setPirce];
[self.collectionView reloadData]; [self.collectionView reloadData];
}); });
_openBtn.enabled = YES;
if (![self.cruuent_nobility_id isExist]) {
[_openBtn setBackgroundImage:[UIImage imageNamed:@"nobility_detail_open_btn_nor"] forState:(UIControlStateNormal)];
return;
}
if (self.currentIndex<index) {
[_openBtn setBackgroundImage:[UIImage imageNamed:@"nobility_detail_open_btn_update"] forState:(UIControlStateNormal)];
return;
}else if (self.currentIndex==index){
[_openBtn setBackgroundImage:[UIImage imageNamed:@"nobility_detail_open_btn_renew"] forState:(UIControlStateNormal)];
}else{
_openBtn.enabled = NO;
}
} }
- (void)cycleScrollView:(GKCycleScrollView *)cycleScrollView didSelectCellAtIndex:(NSInteger)index { - (void)cycleScrollView:(GKCycleScrollView *)cycleScrollView didSelectCellAtIndex:(NSInteger)index {
@@ -226,7 +239,8 @@
-(UIButton *)openBtn{ -(UIButton *)openBtn{
if (!_openBtn) { if (!_openBtn) {
_openBtn = [[UIButton alloc] initWithFrame:CGRectMake(SCREEN_WIDTH-16-128, 19, 128, 41)]; _openBtn = [[UIButton alloc] initWithFrame:CGRectMake(SCREEN_WIDTH-16-128, 19, 128, 41)];
[_openBtn setBackgroundImage:[UIImage imageNamed:@"nobility_detail_open_btn"] forState:(UIControlStateNormal)]; [_openBtn setBackgroundImage:[UIImage imageNamed:@"nobility_detail_open_btn_nor"] forState:(UIControlStateNormal)];
[_openBtn setBackgroundImage:[UIImage imageNamed:@"nobility_detail_open_btn_disable"] forState:(UIControlStateDisabled)];
[_openBtn addTarget:self action:@selector(openAction) forControlEvents:(UIControlEventTouchUpInside)];; [_openBtn addTarget:self action:@selector(openAction) forControlEvents:(UIControlEventTouchUpInside)];;
} }
return _openBtn; return _openBtn;

View File

@@ -91,7 +91,8 @@
_tableView.backgroundColor = [UIColor whiteColor]; _tableView.backgroundColor = [UIColor whiteColor];
_tableView.tableFooterView = [UIView new]; _tableView.tableFooterView = [UIView new];
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone; _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_tableView.rowHeight = 66; _tableView.estimatedRowHeight = 66;
_tableView.rowHeight = UITableViewAutomaticDimension;
MJWeakSelf MJWeakSelf
_tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{ _tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
weakSelf.page = 1; weakSelf.page = 1;

View File

@@ -33,6 +33,9 @@ NS_ASSUME_NONNULL_BEGIN
/// 是否为爵位礼物 0 打开 1 锁住 /// 是否为爵位礼物 0 打开 1 锁住
@property (nonatomic,strong)NSString *is_lock; @property (nonatomic,strong)NSString *is_lock;
/// 是否为爵位礼物 0 打开 1 锁住
@property (nonatomic,strong)NSString *is_cp;
@property (nonatomic,assign)BOOL isSelected; @property (nonatomic,assign)BOOL isSelected;
@end @end

View File

@@ -8,9 +8,10 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "QXGiftModel.h" #import "QXGiftModel.h"
#import "QXSongListModel.h" #import "QXSongListModel.h"
#import "QXUserSongListModel.h"
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@class QXRoomInfoModel,QXRoomPitModel,QXRoomOwnerModel,QXHeadLineModel,QXRoomAuction,QXRoomAuctionUser,QXRoomCpUser,QXRoomPkInfo,QXRoomFriendInfo,QXRoomFriendHeartListModel,QXRoomActivitySubModel,QXRoomActivityModel; @class QXRoomInfoModel,QXRoomPitModel,QXRoomOwnerModel,QXHeadLineModel,QXRoomAuction,QXRoomAuctionUser,QXRoomCpUser,QXRoomPkInfo,QXRoomFriendInfo,QXRoomFriendHeartListModel,QXRoomActivitySubModel,QXRoomActivityModel,QXSingerInfo;
@interface QXRoomModel : NSObject @interface QXRoomModel : NSObject
/// 房间信息 /// 房间信息
@property (nonatomic,strong)QXRoomInfoModel *room_info; @property (nonatomic,strong)QXRoomInfoModel *room_info;
@@ -20,6 +21,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic,strong)QXRoomOwnerModel *user_info; @property (nonatomic,strong)QXRoomOwnerModel *user_info;
/// 当前演唱者信息 /// 当前演唱者信息
@property (nonatomic,strong)QXSongListModel *song_user_info; @property (nonatomic,strong)QXSongListModel *song_user_info;
/// 点唱房演唱者信息
@property (nonatomic,strong)QXSingerInfo *singer_info;
/// 下一首歌曲信息 /// 下一首歌曲信息
@property (nonatomic,strong)QXSongListModel *nextInfo; @property (nonatomic,strong)QXSongListModel *nextInfo;
/// 拍卖房信息 /// 拍卖房信息
@@ -375,4 +378,11 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic,strong)NSString *xlh_status; @property (nonatomic,strong)NSString *xlh_status;
@property (nonatomic,assign)long end_time; @property (nonatomic,assign)long end_time;
@end @end
@interface QXSingerInfo : NSObject
/// 心动值
@property (nonatomic,strong)QXUserSongListModel *song_info;
@property (nonatomic,strong)QXUserSongListModel *next_song_info;
@end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@@ -21,6 +21,7 @@
@"song_pit_list":@"QXRoomPitModel", @"song_pit_list":@"QXRoomPitModel",
@"friend_info":@"QXRoomFriendInfo", @"friend_info":@"QXRoomFriendInfo",
@"gift_cycle":@"QXRoomActivityModel", @"gift_cycle":@"QXRoomActivityModel",
@"singer_info":@"QXSingerInfo",
}; };
} }
@@ -144,3 +145,14 @@
@end @end
@implementation QXSingerInfo
+(NSDictionary<NSString *,id> *)modelContainerPropertyGenericClass{
return @{
@"song_info" : @"QXUserSongListModel",
@"next_song_info" : @"QXUserSongListModel",
};
}
@end

View File

@@ -7,7 +7,7 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@class QXRelationshipListModel; @class QXRelationshipListModel,QXUserCpInfoModel;
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@interface QXUserModel : NSObject @interface QXUserModel : NSObject
@@ -47,6 +47,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic,strong)NSString *is_hide; @property (nonatomic,strong)NSString *is_hide;
/// 当前状态0-取消隐身1-隐身进入 /// 当前状态0-取消隐身1-隐身进入
@property (nonatomic,strong)NSString *hide_status; @property (nonatomic,strong)NSString *hide_status;
/// 当前状态:-1 未认证歌手, 0待审核 1已认证 2被拒绝
@property (nonatomic,strong)NSString *singer_status;
/// 在线状态 /// 在线状态
@property (nonatomic,assign)BOOL is_online; @property (nonatomic,assign)BOOL is_online;
/// 1 能聊天 0不能聊天 /// 1 能聊天 0不能聊天
@@ -124,6 +126,8 @@ NS_ASSUME_NONNULL_BEGIN
/// 是否使用靓号 0未使用 1 已使用 /// 是否使用靓号 0未使用 1 已使用
@property (nonatomic,strong)NSString *is_use_code; @property (nonatomic,strong)NSString *is_use_code;
@property (nonatomic,strong)QXUserCpInfoModel *cp_info;
-(instancetype)copyModel; -(instancetype)copyModel;
@end @end
@@ -208,8 +212,10 @@ NS_ASSUME_NONNULL_BEGIN
/// 角色 1-房主 > 2-管理员 > 3主持人 >4 普通用户 排序 /// 角色 1-房主 > 2-管理员 > 3主持人 >4 普通用户 排序
@property (nonatomic,strong)NSString *role; @property (nonatomic,strong)NSString *role;
@property (nonatomic,strong)QXRelationshipListModel *qinmi; @property (nonatomic,strong)QXUserCpInfoModel *cp_info;
@property (nonatomic,strong)QXRelationshipListModel *zhenai;
//@property (nonatomic,strong)QXRelationshipListModel *qinmi;
//@property (nonatomic,strong)QXRelationshipListModel *zhenai;
@end @end
@@ -254,7 +260,23 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic,strong)NSString *image; @property (nonatomic,strong)NSString *image;
/// 亲密拍心动值 /// 亲密拍心动值
@property (nonatomic,strong)NSString *heart_value; @property (nonatomic,strong)NSString *heart_value;
@property (nonatomic,strong)NSString *sex2;
@property (nonatomic,strong)NSString *sex1;
/// 1-置顶0-不置顶 /// 1-置顶0-不置顶
@property (nonatomic,strong)NSString *is_top; @property (nonatomic,strong)NSString *is_top;
@end @end
@interface QXUserCpInfoModel : NSObject
@property (nonatomic,strong)NSString *name;
@property (nonatomic,strong)NSString *user_id1;
@property (nonatomic,strong)NSString *user_id2;
@property (nonatomic,strong)NSString *level;
@property (nonatomic,strong)NSString *exp;
/// 挂件(装扮)地址
@property (nonatomic,strong)NSString *pendant;
/// 挂件上的头像位置0-上1-右上2-右3-右下4-下5-左下6-左7-左上'
@property (nonatomic,strong)NSString *direction;
@property (nonatomic,strong)QXUserModel *user_info1;
@property (nonatomic,strong)QXUserModel *user_info2;
@end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@@ -16,7 +16,10 @@
+(NSDictionary<NSString *,id> *)modelContainerPropertyGenericClass{ +(NSDictionary<NSString *,id> *)modelContainerPropertyGenericClass{
return @{@"tag_list" : @"QXUserTag"}; return @{
@"tag_list" : @"QXUserTag",
@"cp_info": @"QXUserCpInfoModel"
};
} }
@@ -56,8 +59,9 @@
+(NSDictionary<NSString *,id> *)modelContainerPropertyGenericClass{ +(NSDictionary<NSString *,id> *)modelContainerPropertyGenericClass{
return @{ return @{
@"qinmi" : @"QXRelationshipListModel", // @"qinmi" : @"QXRelationshipListModel",
@"zhenai" : @"QXRelationshipListModel" // @"zhenai" : @"QXRelationshipListModel"
@"cp_info": @"QXUserCpInfoModel"
}; };
} }
@@ -79,3 +83,17 @@
@end @end
@implementation QXUserCpInfoModel
+(NSDictionary<NSString *,id> *)modelContainerPropertyGenericClass{
return @{
// @"qinmi" : @"QXRelationshipListModel",
// @"zhenai" : @"QXRelationshipListModel"
@"user_info1": @"QXUserModel",
@"user_info2": @"QXUserModel",
};
}
@end

View File

@@ -28,6 +28,8 @@
#import "QXNobilityModel.h" #import "QXNobilityModel.h"
#import "QXNobilityListModel.h" #import "QXNobilityListModel.h"
#import "QXNobilityGetPriceModel.h" #import "QXNobilityGetPriceModel.h"
#import "QXUserSongListModel.h"
#import "QXRoomBestFriendModel.h"
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@@ -1186,6 +1188,99 @@ NS_ASSUME_NONNULL_BEGIN
successBlock:(void (^)(NSDictionary* dict))successBlock successBlock:(void (^)(NSDictionary* dict))successBlock
failBlock:(void (^)(NSError * error, NSString * msg))failBlock; failBlock:(void (^)(NSError * error, NSString * msg))failBlock;
/**
歌手认证
*/
+(void)singerAuthWithSong:(NSString*)song
successBlock:(void (^)(NSDictionary* dict))successBlock
failBlock:(void (^)(NSError * error, NSString * msg))failBlock;
/**
用户歌单
*/
+(void)getUserSongListWithRoomId:(NSString*)room_id
user_id:(NSString*)user_id
page:(NSInteger)page
SuccessBlock:(void (^)(NSArray<QXUserSongListModel*>* list,NSString*count))successBlock
failBlock:(void (^)(NSError * error, NSString * msg))failBlock;
/**
用户添加/修改/删除歌曲
type 0 添加 1 修改 2 删除
*/
+(void)mineUserAddAndDeleteAndEditWithType:(NSInteger)type
Id:(NSString*)Id
songName:(NSString*)songName
giftId:(NSString*)giftId
giftNum:(NSString*)giftNum
successBlock:(void (^)(NSDictionary* dict))successBlock
failBlock:(void (^)(NSError * error, NSString * msg))failBlock;
/**
点歌
*/
+(void)requestSongWithSongId:(NSString*)songId
roomId:(NSString*)roomId
successBlock:(void (^)(NSDictionary* dict))successBlock
failBlock:(void (^)(NSError * error, NSString * msg))failBlock;
/**
点歌列表
*/
+(void)requestSongWithRoomId:(NSString*)roomId
type:(NSInteger)type
page:(NSInteger)page
successBlock:(void (^)(NSArray<QXUserSongListModel*>* list,NSString*count))successBlock
failBlock:(void (^)(NSError * error, NSString * msg))failBlock;
/**
歌曲置顶
*/
+(void)requestSongToTopWithId:(NSString*)Id
successBlock:(void (^)(NSDictionary* dict))successBlock
failBlock:(void (^)(NSError * error, NSString * msg))failBlock;
/**
获取点歌房歌曲数量
*/
+(void)requestSongCountWithRoomId:(NSString*)roomId
successBlock:(void (^)(QXUserSongListCount*model))successBlock
failBlock:(void (^)(NSError * error, NSString * msg))failBlock;
/**
点唱房切歌
*/
+(void)requsetSongNextActionWithId:(NSString*)Id
successBlock:(void (^)(NSDictionary* dict))successBlock
failBlock:(void (^)(NSError * error, NSString * msg))failBlock;
/**
cp礼物回赠
*/
+(void)userCpReSendWithGiftId:(NSString *)giftId
userId:(NSString*)userId
roomId:(NSString*)roomId
successBlock:(void (^)(NSDictionary* dict))successBlock
failBlock:(void (^)(NSError * error, NSString * msg))failBlock;
/**
获取挚友列表
*/
+(void)userBestFriendsListWithUserId:(NSString*)userId
page:(NSInteger)page
successBlock:(void (^)(QXRoomBestFriendModel* model))successBlock
failBlock:(void (^)(NSError * error, NSString * msg))failBlock;
/**
更多挚友列表
*/
+(void)userBestFriendsMoreListWithUserId:(NSString*)userId
relation_id:(NSString*)relation_id
successBlock:(void (^)(NSArray< QXRelationshipListModel*>* model))successBlock
failBlock:(void (^)(NSError * error, NSString * msg))failBlock;
@end @end

View File

@@ -22,6 +22,7 @@
[QXGlobal shareGlobal].loginModel.nickname_color = userModel.nickname_color; [QXGlobal shareGlobal].loginModel.nickname_color = userModel.nickname_color;
[QXGlobal shareGlobal].loginModel.is_hide = userModel.is_hide; [QXGlobal shareGlobal].loginModel.is_hide = userModel.is_hide;
[QXGlobal shareGlobal].loginModel.hide_status = userModel.hide_status; [QXGlobal shareGlobal].loginModel.hide_status = userModel.hide_status;
[QXGlobal shareGlobal].loginModel.singer_status = userModel.singer_status;
[[QXGlobal shareGlobal] updateUserInfoWithMolde:[QXGlobal shareGlobal].loginModel]; [[QXGlobal shareGlobal] updateUserInfoWithMolde:[QXGlobal shareGlobal].loginModel];
BOOL api_version = [responseObject[@"api_version"] boolValue]; BOOL api_version = [responseObject[@"api_version"] boolValue];
[QXGlobal shareGlobal].isAppStore = api_version; [QXGlobal shareGlobal].isAppStore = api_version;
@@ -687,10 +688,30 @@
@"pit_number":pit_number?pit_number:@"", @"pit_number":pit_number?pit_number:@"",
@"heart_id":heart_id?heart_id:@"" @"heart_id":heart_id?heart_id:@""
}; };
__block NSString *userId = to_uid;
[[QXRequset shareInstance] postWithUrl:QXSendGift parameters:parameters needCache:NO success:^(id responseObject) { [[QXRequset shareInstance] postWithUrl:QXSendGift parameters:parameters needCache:NO success:^(id responseObject) {
if (successBlock) { if (successBlock) {
successBlock(responseObject[@"data"]); successBlock(responseObject[@"data"]);
} }
// NSDictionary *cp_type = [NSDictionary stringWithFormat:@"%@",responseObject[@"data"][@"cp_type"]];
id object = responseObject[@"data"][@"cp_type"];
if ([object isKindOfClass:[NSDictionary class]]) {
NSDictionary *cpDict = (NSDictionary *)object;
NSString *cp_type = [NSString stringWithFormat:@"%@",cpDict[@"cp_type"]];
if (cp_type.intValue == 1) {
/// cp
NSString *jsonStr = [cpDict jsonStringEncoded];
[[QXRoomMessageManager shared] sendC2CMessage:jsonStr messageType:(QXRoomMessageTypeSendAndRecieveCpHeartSignal) userId:userId];
}else if (cp_type.intValue == 2){
/// cp
NSString *jsonStr = [cpDict jsonStringEncoded];
[[QXRoomMessageManager shared] sendC2CMessage:jsonStr messageType:(QXRoomMessageTypeCpHeartFinished) userId:userId];
[[QXRoomMessageManager shared] showCpFinishedAlertViewWithText:[NSString stringWithFormat:@"%@",cpDict[@"text"]]];
}else{
}
}
} fail:^(NSError *error, NSString *msg, NSURLSessionDataTask *task) { } fail:^(NSError *error, NSString *msg, NSURLSessionDataTask *task) {
failBlock(error,msg); failBlock(error,msg);
}]; }];
@@ -2314,4 +2335,213 @@
}]; }];
} }
+(void)singerAuthWithSong:(NSString*)song
successBlock:(void (^)(NSDictionary* dict))successBlock
failBlock:(void (^)(NSError * error, NSString * msg))failBlock{
NSDictionary *parameters =@{
@"song":song?song:@"",
};
[[QXRequset shareInstance] postWithUrl:QXMineSingerAuth parameters:parameters needCache:NO success:^(id responseObject) {
if (successBlock) {
successBlock(responseObject[@"data"]);
}
} fail:^(NSError *error, NSString *msg, NSURLSessionDataTask *task) {
failBlock(error,msg);
}];
}
+(void)getUserSongListWithRoomId:(NSString *)room_id
user_id:(NSString *)user_id
page:(NSInteger)page
SuccessBlock:(void (^)(NSArray<QXUserSongListModel*>* list,NSString*count))successBlock
failBlock:(void (^)(NSError * _Nonnull, NSString * _Nonnull))failBlock{
NSDictionary *parameters =@{
@"room_id":room_id?room_id:@"",
@"user_id":user_id?user_id:@"",
@"page":[NSNumber numberWithInteger:page]
};
[[QXRequset shareInstance] postWithUrl:QXMineGetSingerSongList parameters:parameters needCache:NO success:^(id responseObject) {
if (successBlock) {
NSArray*list = [NSArray yy_modelArrayWithClass:[QXUserSongListModel class] json:responseObject[@"data"][@"lists"]];
NSString*count = [NSString stringWithFormat:@"%@",responseObject[@"data"][@"count"]];
successBlock(list,count);
}
} fail:^(NSError *error, NSString *msg, NSURLSessionDataTask *task) {
failBlock(error,msg);
}];
}
+(void)mineUserAddAndDeleteAndEditWithType:(NSInteger)type
Id:(NSString*)Id
songName:(NSString*)songName
giftId:(NSString*)giftId
giftNum:(NSString*)giftNum
successBlock:(void (^)(NSDictionary* dict))successBlock
failBlock:(void (^)(NSError * error, NSString * msg))failBlock{
NSString *url = QXMineSingerAddSong;
if (type == 0) {
url = QXMineSingerAddSong;
}else if(type == 1){
url = QXMineSingerEidtSong;
}else{
url = QXMineSingerDeleteSong;
}
NSDictionary *parameters =@{
@"id":Id?:@"",
@"song_name":songName?:@"",
@"gift_id":giftId?:@"",
@"gift_num":giftNum?:@"",
};
[[QXRequset shareInstance] postWithUrl:url parameters:parameters needCache:NO success:^(id responseObject) {
if (successBlock) {
successBlock(responseObject[@"data"]);
}
} fail:^(NSError *error, NSString *msg, NSURLSessionDataTask *task) {
failBlock(error,msg);
}];
}
/**
*/
+(void)requestSongWithSongId:(NSString*)songId
roomId:(NSString*)roomId
successBlock:(void (^)(NSDictionary* dict))successBlock
failBlock:(void (^)(NSError * error, NSString * msg))failBlock{
NSDictionary *parameters =@{
@"song_id":songId?:@"",
@"room_id":roomId?:@"",
};
[[QXRequset shareInstance] postWithUrl:QXRoomRequestSong parameters:parameters needCache:NO success:^(id responseObject) {
if (successBlock) {
successBlock(responseObject[@"data"]);
}
} fail:^(NSError *error, NSString *msg, NSURLSessionDataTask *task) {
failBlock(error,msg);
}];
}
/**
*/
+(void)requestSongWithRoomId:(NSString*)roomId
type:(NSInteger)type
page:(NSInteger)page
successBlock:(void (^)(NSArray<QXUserSongListModel*>* list,NSString*count))successBlock
failBlock:(void (^)(NSError * error, NSString * msg))failBlock{
NSDictionary *parameters =@{
@"type":[NSNumber numberWithInteger:type],
@"room_id":roomId?:@"",
@"page":[NSNumber numberWithInteger:page]
};
[[QXRequset shareInstance] postWithUrl:QXRoomAllSongList parameters:parameters needCache:NO success:^(id responseObject) {
if (successBlock) {
NSArray*list = [NSArray yy_modelArrayWithClass:[QXUserSongListModel class] json:responseObject[@"data"][@"lists"]];
NSString*count = [NSString stringWithFormat:@"%@",responseObject[@"data"][@"count"]];
successBlock(list,count);
}
} fail:^(NSError *error, NSString *msg, NSURLSessionDataTask *task) {
failBlock(error,msg);
}];
}
/**
*/
+(void)requestSongToTopWithId:(NSString*)Id
successBlock:(void (^)(NSDictionary* dict))successBlock
failBlock:(void (^)(NSError * error, NSString * msg))failBlock{
NSDictionary *parameters =@{
@"id":Id?:@"",
};
[[QXRequset shareInstance] postWithUrl:QXRoomRequestSongTop parameters:parameters needCache:NO success:^(id responseObject) {
if (successBlock) {
successBlock(responseObject[@"data"]);
}
} fail:^(NSError *error, NSString *msg, NSURLSessionDataTask *task) {
failBlock(error,msg);
}];
}
+(void)requestSongCountWithRoomId:(NSString*)roomId
successBlock:(void (^)(QXUserSongListCount*model))successBlock
failBlock:(void (^)(NSError * error, NSString * msg))failBlock{
NSDictionary *parameters =@{
@"room_id":roomId?:@"",
};
[[QXRequset shareInstance] postWithUrl:QXRoomRequestSongCount parameters:parameters needCache:NO success:^(id responseObject) {
if (successBlock) {
QXUserSongListCount *countModel = [QXUserSongListCount yy_modelWithJSON:responseObject[@"data"]];
successBlock(countModel);
}
} fail:^(NSError *error, NSString *msg, NSURLSessionDataTask *task) {
failBlock(error,msg);
}];
}
+(void)requsetSongNextActionWithId:(NSString *)Id successBlock:(void (^)(NSDictionary * _Nonnull))successBlock failBlock:(void (^)(NSError * _Nonnull, NSString * _Nonnull))failBlock{
NSDictionary *parameters =@{
@"id":Id?:@"",
};
[[QXRequset shareInstance] postWithUrl:QXRoomRequestSongNext parameters:parameters needCache:NO success:^(id responseObject) {
if (successBlock) {
successBlock(responseObject[@"data"]);
}
} fail:^(NSError *error, NSString *msg, NSURLSessionDataTask *task) {
failBlock(error,msg);
}];
}
+(void)userCpReSendWithGiftId:(NSString *)giftId userId:(NSString*)userId roomId:(NSString*)roomId successBlock:(void (^)(NSDictionary * _Nonnull))successBlock failBlock:(void (^)(NSError * _Nonnull, NSString * _Nonnull))failBlock{
NSDictionary *parameters =@{
@"gift_id":giftId?:@"",
@"user_id":userId?:@"",
@"room_id":roomId?:@""
};
[[QXRequset shareInstance] postWithUrl:QXUserCpResend parameters:parameters needCache:NO success:^(id responseObject) {
if (successBlock) {
successBlock(responseObject[@"data"]);
}
} fail:^(NSError *error, NSString *msg, NSURLSessionDataTask *task) {
failBlock(error,msg);
}];
}
+(void)userBestFriendsListWithUserId:(NSString*)userId
page:(NSInteger)page
successBlock:(void (^)(QXRoomBestFriendModel* model))successBlock
failBlock:(void (^)(NSError * error, NSString * msg))failBlock{
NSDictionary *parameters =@{
@"user_id":userId?:@"",
@"page":[NSNumber numberWithInteger:page]
};
[[QXRequset shareInstance] postWithUrl:QXBestFriendsList parameters:parameters needCache:NO success:^(id responseObject) {
if (successBlock) {
QXRoomBestFriendModel *model = [QXRoomBestFriendModel yy_modelWithJSON:responseObject[@"data"]];
successBlock(model);
}
} fail:^(NSError *error, NSString *msg, NSURLSessionDataTask *task) {
failBlock(error,msg);
}];
}
+(void)userBestFriendsMoreListWithUserId:(NSString*)userId
relation_id:(NSString*)relation_id
successBlock:(void (^)(NSArray< QXRelationshipListModel*>* model))successBlock
failBlock:(void (^)(NSError * error, NSString * msg))failBlock{
NSDictionary *parameters =@{
@"user_id":userId?:@"",
@"relation_id":relation_id?:@""
};
[[QXRequset shareInstance] postWithUrl:QXBestFriendsMoreList parameters:parameters needCache:NO success:^(id responseObject) {
if (successBlock) {
NSArray *list = [NSArray yy_modelArrayWithClass:[QXRelationshipListModel class] json:responseObject[@"data"]];
successBlock(list);
}
} fail:^(NSError *error, NSString *msg, NSURLSessionDataTask *task) {
failBlock(error,msg);
}];
}
@end @end

View File

@@ -87,7 +87,9 @@
self.nameLabel = [[CKShimmerLabel alloc] initWithFrame:CGRectMake(self.userHeaderView.right+6, self.userHeaderView.top+5, self.width-self.userHeaderView.right-16-6, 22)]; self.nameLabel = [[CKShimmerLabel alloc] initWithFrame:CGRectMake(self.userHeaderView.right+6, self.userHeaderView.top+5, self.width-self.userHeaderView.right-16-6, 22)];
self.nameLabel.shimmerWidth = 20; self.nameLabel.shimmerWidth = 20;
self.nameLabel.shimmerRadius = 20; self.nameLabel.shimmerRadius = 20;
self.nameLabel.shimmerColor = [UIColor yellowColor]; self.nameLabel.durationTime = 1;
self.nameLabel.text = @"羽声语音";
// self.nameLabel.shimmerColor = [UIColor yellowColor];
self.nameLabel.repeat = YES; self.nameLabel.repeat = YES;
self.nameLabel.textColor = RGB16A(0xffffff,0.85); self.nameLabel.textColor = RGB16A(0xffffff,0.85);
self.nameLabel.font = [UIFont boldSystemFontOfSize:18]; self.nameLabel.font = [UIFont boldSystemFontOfSize:18];
@@ -321,6 +323,7 @@
if (QXGlobal.shareGlobal.isOpenRecharge) { if (QXGlobal.shareGlobal.isOpenRecharge) {
[self.toolsArray insertObject:self.rechargeModel atIndex:0]; [self.toolsArray insertObject:self.rechargeModel atIndex:0];
} }
[self.collectionView reloadData];
} }
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return self.toolsArray.count; return self.toolsArray.count;
@@ -367,9 +370,10 @@
[self.userHeaderView setHeadIcon:userModel.avatar dress:userModel.dress]; [self.userHeaderView setHeadIcon:userModel.avatar dress:userModel.dress];
[self.userHeaderView.nobilityImageView sd_setImageWithURL:[NSURL URLWithString:userModel.nobility_image]]; [self.userHeaderView.nobilityImageView sd_setImageWithURL:[NSURL URLWithString:userModel.nobility_image]];
if ([userModel.nickname_color isExist]) { if ([userModel.nickname_color isExist]) {
self.nameLabel.textColor = [UIColor colorWithHexString:userModel.nickname_color]; self.nameLabel.shimmerColor = [UIColor colorWithHexString:userModel.nickname_color];
[self.nameLabel startShimmer];
}else{ }else{
self.nameLabel.textColor = RGB16A(0xffffff,0.85); [self.nameLabel stopShimmer];
} }
self.nameLabel.text = userModel.nickname; self.nameLabel.text = userModel.nickname;
self.idLabel.text = [NSString stringWithFormat:@"ID:%@",userModel.user_code]; self.idLabel.text = [NSString stringWithFormat:@"ID:%@",userModel.user_code];

View File

@@ -27,6 +27,10 @@ typedef NS_ENUM(NSInteger) {
QXMineServiceTypeReport = 47, QXMineServiceTypeReport = 47,
/// 个税客服 /// 个税客服
QXMineServiceTypeCustomerService = 48, QXMineServiceTypeCustomerService = 48,
/// 歌手认证
QXMineServiceTypeSingerAuth = 49,
/// 我的歌单
QXMineServiceTypeSongList = 50,
}QXMineServiceType; }QXMineServiceType;
@protocol QXMineServiceCellDelegate <NSObject> @protocol QXMineServiceCellDelegate <NSObject>

View File

@@ -115,6 +115,7 @@
[self.moreArray insertObject:self.inviteModel atIndex:1]; [self.moreArray insertObject:self.inviteModel atIndex:1];
} }
} }
[self.collectionView reloadData];
} }
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return self.isMore?self.moreArray.count:self.serviceArray.count; return self.isMore?self.moreArray.count:self.serviceArray.count;
@@ -196,11 +197,23 @@
md4.icon = @"service_customer_service"; md4.icon = @"service_customer_service";
md4.type = QXMineServiceTypeCustomerService; md4.type = QXMineServiceTypeCustomerService;
QXServiceModel *md5 = [[QXServiceModel alloc] init];
md5.title = @"歌手认证";
md5.icon = @"service_singer_auth";
md5.type = QXMineServiceTypeSingerAuth;
QXServiceModel *md6 = [[QXServiceModel alloc] init];
md6.title = @"我的歌单";
md6.icon = @"service_songlist";
md6.type = QXMineServiceTypeSongList;
_moreArray = [NSMutableArray arrayWithArray:@[ _moreArray = [NSMutableArray arrayWithArray:@[
md1, md1,
md2, md2,
md3, md3,
md4, md4,
md5,
md6,
]]; ]];
} }

View File

@@ -11,6 +11,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface QXUserHomeHeaderView : UIView @interface QXUserHomeHeaderView : UIView
@property (nonatomic,strong)QXUserHomeModel *model; @property (nonatomic,strong)QXUserHomeModel *model;
@property (nonatomic,strong)NSString *userId;
@end @end
@interface QXTagImageCell : UICollectionViewCell @interface QXTagImageCell : UICollectionViewCell

View File

@@ -12,24 +12,35 @@
#import "NSString+QX.h" #import "NSString+QX.h"
#import "QXDynamicNetwork.h" #import "QXDynamicNetwork.h"
#import "QXChatViewController.h" #import "QXChatViewController.h"
#import "CKShimmerLabel.h"
#import "QXUserCpDressView.h"
#import "QXUserCpCardView.h"
#import "QXGiftWallViewController.h"
#import "QXHeartBeatSpaceViewController.h"
@interface QXUserHomeHeaderView()<UICollectionViewDelegate,UICollectionViewDataSource> @interface QXUserHomeHeaderView()<UICollectionViewDelegate,UICollectionViewDataSource>
//@property (nonatomic,strong) CKShimmerLabel * tempName;
@property (nonatomic,strong) QXSeatHeaderView* headerView; @property (nonatomic,strong) QXSeatHeaderView* headerView;
@property (nonatomic,strong) UIView * whiteBgView; @property (nonatomic,strong) UIView * whiteBgView;
@property (nonatomic,strong) UIView * grayBgView; @property (nonatomic,strong) UIView * grayBgView;
@property (nonatomic,strong) UILabel * nameLabel; @property (nonatomic,strong) CKShimmerLabel * nameLabel;
@property (nonatomic,strong) UILabel * idLabel; @property (nonatomic,strong) UILabel * idLabel;
@property (nonatomic,strong) UILabel * ageLabel; //@property (nonatomic,strong) UILabel * ageLabel;
@property (nonatomic,strong) UIImageView * guildBgImageView;
@property (nonatomic,strong) UILabel * guildLabel; @property (nonatomic,strong) UILabel * guildLabel;
@property (nonatomic,strong) UICollectionView * collectionView; @property (nonatomic,strong) UICollectionView * collectionView;
@property (nonatomic,strong) NSMutableArray * tagArray; @property (nonatomic,strong) NSMutableArray * tagArray;
@property (nonatomic,strong) UILabel *introduceLabel; @property (nonatomic,strong) UILabel *introduceLabel;
@property (nonatomic,strong) UICollectionView *inCollectionView; @property (nonatomic,strong) UICollectionView *inCollectionView;
@property (nonatomic, strong) UIImageView *useCodeImageView; @property (nonatomic, strong) UIImageView *useCodeImageView;
@property (nonatomic, strong)UIImageView *sexImageView; //@property (nonatomic, strong)UIImageView *sexImageView;
@property (nonatomic,strong) UIButton *followBtn; @property (nonatomic,strong) UIButton *followBtn;
@property (nonatomic,strong) UIButton *playBtn; @property (nonatomic,strong) UIButton *playBtn;
@property (nonatomic,strong) QXUserCpDressView *cpDressView;
@property (nonatomic,strong) QXUserCpCardView *cpCardView;
@property (nonatomic,strong) UIButton *giftWallBtn;
@end @end
@implementation QXUserHomeHeaderView @implementation QXUserHomeHeaderView
@@ -45,8 +56,8 @@
-(void)initSubviews{ -(void)initSubviews{
self.backgroundColor = [UIColor clearColor]; self.backgroundColor = [UIColor clearColor];
self.headerView = [[QXSeatHeaderView alloc] initWithFrame:CGRectMake(32, 26, 70, 84)];
self.headerView = [[QXSeatHeaderView alloc] initWithFrame:CGRectMake(32, 46, 70, 70)];
[self.headerView addRoundedCornersWithRadius:35]; [self.headerView addRoundedCornersWithRadius:35];
[self addSubview:self.headerView]; [self addSubview:self.headerView];
[self.headerView mas_makeConstraints:^(MASConstraintMaker *make) { [self.headerView mas_makeConstraints:^(MASConstraintMaker *make) {
@@ -56,34 +67,59 @@
make.top.mas_equalTo(26); make.top.mas_equalTo(26);
}]; }];
self.nameLabel = [[CKShimmerLabel alloc] initWithFrame:CGRectMake(32, self.headerView.bottom+4, 200, 24)];
// self.nameLabel.text = @"羽声语音";
self.nameLabel = [[UILabel alloc] init]; self.nameLabel.shimmerWidth = 20;
self.nameLabel.shimmerRadius = 20;
self.nameLabel.durationTime = 1;
self.nameLabel.repeat = YES;
self.nameLabel.textColor = QXConfig.textColor; self.nameLabel.textColor = QXConfig.textColor;
self.nameLabel.font = [UIFont boldSystemFontOfSize:16]; // self.nameLabel.shimmerColor = [UIColor yellowColor];
self.nameLabel.font = [UIFont boldSystemFontOfSize:18];
// [self.nameLabel startShimmer];
[self addSubview:self.nameLabel]; [self addSubview:self.nameLabel];
[self.nameLabel mas_makeConstraints:^(MASConstraintMaker *make) { [self.nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.headerView); make.left.equalTo(self.headerView);
make.height.mas_equalTo(24); make.height.mas_equalTo(24);
make.top.equalTo(self.headerView.mas_bottom).offset(4); make.top.equalTo(self.headerView.mas_bottom).offset(4);
make.width.mas_greaterThanOrEqualTo(200);
}]; }];
self.sexImageView = [[UIImageView alloc] init]; self.followBtn = [[UIButton alloc] initWithFrame:CGRectMake(self.playBtn.left-6-91, self.whiteBgView.top+10, 91, 12)];
[self addSubview:self.sexImageView]; [self.followBtn setTitle:QXText(@"关注") forState:(UIControlStateNormal)];
[self.sexImageView mas_makeConstraints:^(MASConstraintMaker *make) { [self.followBtn setTitle:QXText(@"已关注") forState:(UIControlStateSelected)];
make.left.equalTo(self.nameLabel.mas_right).offset(5); [self.followBtn setTitleColor:QXConfig.btnTextColor forState:(UIControlStateNormal)];
[self.followBtn setTitleColor:RGB16(0x999999) forState:(UIControlStateSelected)];
[self.followBtn setBackgroundImage:[UIImage imageWithColor:QXConfig.themeColor] forState:UIControlStateNormal];
[self.followBtn setBackgroundImage:[UIImage imageWithColor:RGB16(0xF1F2F3)] forState:UIControlStateSelected];
self.followBtn.titleLabel.font = [UIFont systemFontOfSize:14];
[self.followBtn addRoundedCornersWithRadius:12];
self.followBtn.hidden = YES;
[self.followBtn addTarget:self action:@selector(followAction) forControlEvents:(UIControlEventTouchUpInside)];
[self addSubview:self.followBtn];
[self.followBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.nameLabel.mas_right).offset(10);
make.width.mas_equalTo(55);
make.height.mas_equalTo(24);
make.centerY.equalTo(self.nameLabel); make.centerY.equalTo(self.nameLabel);
make.height.width.mas_equalTo(16);
}]; }];
// self.sexImageView = [[UIImageView alloc] init];
// [self addSubview:self.sexImageView];
// [self.sexImageView mas_makeConstraints:^(MASConstraintMaker *make) {
// make.left.equalTo(self.nameLabel.mas_right).offset(5);
// make.centerY.equalTo(self.nameLabel);
// make.height.width.mas_equalTo(16);
// }];
self.idLabel = [[UILabel alloc] init]; self.idLabel = [[UILabel alloc] init];
self.idLabel.textColor = RGB16(0x999999); self.idLabel.textColor = RGB16(0x999999);
self.idLabel.font = [UIFont boldSystemFontOfSize:12]; self.idLabel.font = [UIFont boldSystemFontOfSize:12];
[self addSubview:self.idLabel]; [self addSubview:self.idLabel];
[self.idLabel mas_makeConstraints:^(MASConstraintMaker *make) { [self.idLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.sexImageView.mas_right).offset(12); make.left.equalTo(self.nameLabel);
make.height.mas_equalTo(24); make.height.mas_equalTo(18);
make.centerY.equalTo(self.nameLabel); make.top.equalTo(self.nameLabel.mas_bottom).offset(5);
}]; }];
self.useCodeImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"mine_usercode_isLiang"]]; self.useCodeImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"mine_usercode_isLiang"]];
@@ -96,16 +132,16 @@
make.centerY.equalTo(self.idLabel); make.centerY.equalTo(self.idLabel);
}]; }];
self.ageLabel = [[UILabel alloc] init]; // self.ageLabel = [[UILabel alloc] init];
self.ageLabel.textColor = RGB16(0x999999); // self.ageLabel.textColor = RGB16(0x999999);
self.ageLabel.font = [UIFont boldSystemFontOfSize:12]; // self.ageLabel.font = [UIFont boldSystemFontOfSize:12];
[self addSubview:self.ageLabel]; // [self addSubview:self.ageLabel];
[self.ageLabel mas_makeConstraints:^(MASConstraintMaker *make) { // [self.ageLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.headerView); // make.left.equalTo(self.headerView);
make.height.mas_equalTo(18); // make.height.mas_equalTo(18);
make.top.equalTo(self.nameLabel.mas_bottom).offset(8); // make.top.equalTo(self.nameLabel.mas_bottom).offset(8);
make.width.mas_greaterThanOrEqualTo(35); // make.width.mas_greaterThanOrEqualTo(35);
}]; // }];
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.itemSize = CGSizeMake(UserIconWidth, UserIconHeight); layout.itemSize = CGSizeMake(UserIconWidth, UserIconHeight);
@@ -118,25 +154,13 @@
[self.collectionView registerClass:[QXTagImageCell class] forCellWithReuseIdentifier:@"QXTagImageCell"]; [self.collectionView registerClass:[QXTagImageCell class] forCellWithReuseIdentifier:@"QXTagImageCell"];
[self addSubview:self.collectionView]; [self addSubview:self.collectionView];
[self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) { [self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.ageLabel.mas_right).offset(8); make.left.equalTo(self.nameLabel);
make.height.mas_equalTo(18); make.height.mas_equalTo(18);
make.centerY.equalTo(self.ageLabel); make.top.equalTo(self.idLabel.mas_bottom).offset(5);
make.width.mas_equalTo(300); make.width.mas_equalTo(ScaleWidth(240));
}]; }];
self.guildLabel = [[UILabel alloc] init];
self.guildLabel.textColor = RGB16(0x999999);
self.guildLabel.text = @"所属公会";
self.guildLabel.font = [UIFont boldSystemFontOfSize:12];
[self addSubview:self.guildLabel];
[self.guildLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.headerView);
make.height.mas_equalTo(18);
make.top.equalTo(self.ageLabel.mas_bottom).offset(8);
make.width.mas_greaterThanOrEqualTo(35);
}];
self.introduceLabel = [[UILabel alloc] init]; self.introduceLabel = [[UILabel alloc] init];
self.introduceLabel.textColor = QXConfig.textColor; self.introduceLabel.textColor = QXConfig.textColor;
self.introduceLabel.font = [UIFont systemFontOfSize:14]; self.introduceLabel.font = [UIFont systemFontOfSize:14];
@@ -144,9 +168,9 @@
[self addSubview:self.introduceLabel]; [self addSubview:self.introduceLabel];
[self.introduceLabel mas_makeConstraints:^(MASConstraintMaker *make) { [self.introduceLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.headerView); make.left.equalTo(self.headerView);
make.top.equalTo(self.guildLabel.mas_bottom).offset(4); make.top.equalTo(self.collectionView.mas_bottom).offset(6);
make.width.mas_equalTo(SCREEN_WIDTH-64); make.width.mas_equalTo(SCREEN_WIDTH-64);
make.height.mas_greaterThanOrEqualTo(22); make.height.mas_greaterThanOrEqualTo(17);
}]; }];
UICollectionViewFlowLayout *inlayout = [[UICollectionViewFlowLayout alloc] init]; UICollectionViewFlowLayout *inlayout = [[UICollectionViewFlowLayout alloc] init];
@@ -164,70 +188,113 @@
make.left.equalTo(self.headerView); make.left.equalTo(self.headerView);
make.height.mas_equalTo(22); make.height.mas_equalTo(22);
make.top.equalTo(self.introduceLabel.mas_bottom).offset(4); make.top.equalTo(self.introduceLabel.mas_bottom).offset(4);
make.width.mas_equalTo(SCREEN_WIDTH-64); make.right.mas_equalTo(-32);
}]; }];
self.whiteBgView = [[UIView alloc] initWithFrame:CGRectMake(0, 46, self.width, 167)]; self.whiteBgView = [[UIView alloc] initWithFrame:CGRectMake(0, 46, self.width, 167)];
self.whiteBgView.backgroundColor = [UIColor whiteColor]; self.whiteBgView.backgroundColor = RGB16(0xffffff);
[self.whiteBgView addRoundedCornersWithRadius:16]; [self.whiteBgView addRoundedCornersWithRadius:16];
[self insertSubview:self.whiteBgView belowSubview:self.headerView]; [self insertSubview:self.whiteBgView belowSubview:self.headerView];
[self.whiteBgView mas_makeConstraints:^(MASConstraintMaker *make) { [self.whiteBgView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(16); make.left.mas_equalTo(0);
make.width.mas_equalTo(SCREEN_WIDTH-32); make.right.mas_equalTo(0);
make.top.equalTo(self.headerView.mas_top).offset(20); make.top.equalTo(self.headerView.mas_top).offset(20);
make.bottom.equalTo(self); make.bottom.equalTo(self.inCollectionView).offset(10);
}]; }];
self.guildBgImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"user_home_guild_bg"]];
[self.whiteBgView addSubview:self.guildBgImageView];
[self.guildBgImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.mas_equalTo(-8);
make.height.mas_equalTo(31);
make.top.mas_equalTo(6);
make.width.mas_equalTo(94);
}];
self.guildLabel = [[UILabel alloc] init];
self.guildLabel.textColor = RGB16(0xffffff);
self.guildLabel.textAlignment = NSTextAlignmentCenter;
self.guildLabel.lineBreakMode = NSLineBreakByClipping;
self.guildLabel.font = [UIFont boldSystemFontOfSize:10];
[self.whiteBgView addSubview:self.guildLabel];
[self.guildLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.guildBgImageView).offset(6);
make.height.mas_equalTo(14);
make.top.equalTo(self.guildBgImageView).offset(6);
make.right.equalTo(self.guildBgImageView).offset(-28);
}];
self.grayBgView = [[UIView alloc] initWithFrame:CGRectMake(0, self.whiteBgView.top+75, self.width, 92)]; self.grayBgView = [[UIView alloc] initWithFrame:CGRectMake(0, self.whiteBgView.top+75, self.width, 92)];
self.grayBgView.backgroundColor = RGB16(0xF6F6F6); self.grayBgView.backgroundColor = RGB16(0xF3F3F3);
[self.grayBgView addRoundedCornersWithRadius:16 byRoundingCorners:(UIRectCornerTopLeft|UIRectCornerTopRight)]; // [self.grayBgView addRoundedCornersWithRadius:16 byRoundingCorners:(UIRectCornerTopLeft|UIRectCornerTopRight)];
[self insertSubview:self.grayBgView belowSubview:self.whiteBgView]; [self insertSubview:self.grayBgView belowSubview:self.whiteBgView];
[self.grayBgView mas_makeConstraints:^(MASConstraintMaker *make) { [self.grayBgView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self); make.left.right.equalTo(self);
make.height.mas_equalTo(92); make.top.equalTo(self.whiteBgView).offset(16);
make.bottom.equalTo(self.whiteBgView); make.bottom.equalTo(self);
}]; }];
self.playBtn = [[UIButton alloc] initWithFrame:CGRectMake(self.playBtn.left-6-91, self.whiteBgView.top+10, 91, 35)]; self.playBtn = [[UIButton alloc] initWithFrame:CGRectMake(self.playBtn.left-6-91, self.whiteBgView.top+10, 91, 24)];
// [self.playBtn setTitle:QXText(@"私信") forState:(UIControlStateNormal)]; // [self.playBtn setTitle:QXText(@"私信") forState:(UIControlStateNormal)];
// [self.playBtn setTitleColor:UIColor.whiteColor forState:(UIControlStateNormal)]; // [self.playBtn setTitleColor:UIColor.whiteColor forState:(UIControlStateNormal)];
// self.playBtn.backgroundColor = RGB16(0x333333); // self.playBtn.backgroundColor = RGB16(0x333333);
self.playBtn.hidden = YES; self.playBtn.hidden = YES;
self.playBtn.titleLabel.font = [UIFont systemFontOfSize:14]; self.playBtn.titleLabel.font = [UIFont systemFontOfSize:14];
[self.playBtn addRoundedCornersWithRadius:17.5]; [self.playBtn addRoundedCornersWithRadius:12];
[self.playBtn addTarget:self action:@selector(playAction) forControlEvents:(UIControlEventTouchUpInside)]; [self.playBtn addTarget:self action:@selector(playAction) forControlEvents:(UIControlEventTouchUpInside)];
[self addSubview:self.playBtn]; [self.whiteBgView addSubview:self.playBtn];
[self.playBtn mas_makeConstraints:^(MASConstraintMaker *make) { [self.playBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.mas_equalTo(-27); make.right.equalTo(self.guildBgImageView.mas_left).offset(-6);
make.width.mas_equalTo(91); make.width.mas_equalTo(59);
make.height.mas_equalTo(35); make.height.mas_equalTo(24);
make.top.equalTo(self.whiteBgView).offset(10); make.centerY.equalTo(self.guildBgImageView).offset(-2);
}]; }];
self.followBtn = [[UIButton alloc] initWithFrame:CGRectMake(self.playBtn.left-6-91, self.whiteBgView.top+10, 91, 35)];
[self.followBtn setTitle:QXText(@"关注") forState:(UIControlStateNormal)];
[self.followBtn setTitle:QXText(@"已关注") forState:(UIControlStateSelected)];
[self.followBtn setTitleColor:QXConfig.btnTextColor forState:(UIControlStateNormal)];
[self.followBtn setTitleColor:RGB16(0x999999) forState:(UIControlStateSelected)];
[self.followBtn setBackgroundImage:[UIImage imageWithColor:QXConfig.themeColor] forState:UIControlStateNormal];
[self.followBtn setBackgroundImage:[UIImage imageWithColor:RGB16(0xF1F2F3)] forState:UIControlStateSelected];
self.followBtn.titleLabel.font = [UIFont systemFontOfSize:14];
[self.followBtn addRoundedCornersWithRadius:17.5];
self.followBtn.hidden = YES;
[self.followBtn addTarget:self action:@selector(followAction) forControlEvents:(UIControlEventTouchUpInside)];
[self addSubview:self.followBtn];
[self.followBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.playBtn.mas_left).offset(-6);
make.width.mas_equalTo(91);
make.height.mas_equalTo(35);
make.centerY.equalTo(self.playBtn);
}];
// self.nameLabel.text = @"张三"; // self.nameLabel.text = @"张三";
// self.idLabel.text = @"313213213"; // self.idLabel.text = @"313213213";
// self.ageLabel.text = @"36岁"; // self.ageLabel.text = @"36岁";
// self.introduceLabel.text = @"个人简介个人简介个人简介个人简个人简介"; // self.introduceLabel.text = @"个人简介个人简介个人简介个人简个人简介";
[self.inCollectionView reloadData]; [self.inCollectionView reloadData];
self.cpDressView = [[QXUserCpDressView alloc] initWithFrame:CGRectMake(self.width-15-ScaleWidth(120), 0, ScaleWidth(120), ScaleWidth(194))];
self.cpDressView.hidden = YES;
[self.whiteBgView addSubview:self.cpDressView];
self.cpCardView = [[QXUserCpCardView alloc] init];
self.cpCardView.hidden = YES;
MJWeakSelf
[self.cpCardView addTapBlock:^(id _Nonnull obj) {
QXHeartBeatSpaceViewController*vc = [[QXHeartBeatSpaceViewController alloc] init];
vc.userId = weakSelf.userId;
[weakSelf.viewController.navigationController pushViewController:vc animated:YES];
}];
[self addSubview:self.cpCardView];
[self.cpCardView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(17);
make.right.mas_equalTo(-17);
make.top.equalTo(self.whiteBgView.mas_bottom).offset(14);
make.height.mas_equalTo(ScaleWidth(100));
}];
self.giftWallBtn = [[UIButton alloc] init];
[self.giftWallBtn addTarget:self action:@selector(giftWallAction) forControlEvents:(UIControlEventTouchUpInside)];
[self.giftWallBtn setBackgroundImage:[UIImage imageNamed:@"user_home_gift_wall"] forState:(UIControlStateNormal)];
[self addSubview:self.giftWallBtn];
[self.giftWallBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(17);
make.right.mas_equalTo(-17);
make.height.mas_equalTo(ScaleWidth(40));
make.top.equalTo(self.cpCardView.mas_bottom).offset(8);
}];
}
-(void)giftWallAction{
QXGiftWallViewController *vc = [[QXGiftWallViewController alloc] init];
vc.userId = self.userId;
[self.viewController.navigationController pushViewController:vc animated:YES];
} }
-(void)followAction{ -(void)followAction{
@@ -270,16 +337,60 @@
} }
-(void)setModel:(QXUserHomeModel *)model{ -(void)setModel:(QXUserHomeModel *)model{
_model = model; _model = model;
// model.nickname = @"大家好撒客户端撒大厦尽快";
// self.tempName.text = model.nickname;
[self.headerView setHeadIcon:model.avatar dress:model.dress]; [self.headerView setHeadIcon:model.avatar dress:model.dress];
[self.headerView.nobilityImageView sd_setImageWithURL:[NSURL URLWithString:model.nobility_image]]; [self.headerView.nobilityImageView sd_setImageWithURL:[NSURL URLWithString:model.nobility_image]];
self.nameLabel.text = model.nickname;
if ([model.nickname_color isExist]) { if ([model.nickname_color isExist]) {
self.nameLabel.textColor = [UIColor colorWithHexString:model.nickname_color]; self.nameLabel.shimmerColor = [UIColor colorWithHexString:model.nickname_color];
[self.nameLabel startShimmer];
// self.tempName.shimmerColor = UIColor.redColor;
// [self.tempName startShimmer];
}else{ }else{
self.nameLabel.textColor = QXConfig.textColor; [self.nameLabel stopShimmer];
} }
self.idLabel.text = [NSString stringWithFormat:@"ID:%@",model.user_code]; self.nameLabel.text = model.nickname;
self.ageLabel.text = [NSString stringWithFormat:@"%@|%ld岁",model.sex.intValue==1?QXText(@"男"):QXText(@"女"),[model.birthday ageWithDateOfBirth]]; [self.nameLabel.contentLabel sizeToFit];
[self.nameLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.headerView);
make.height.mas_equalTo(24);
make.top.equalTo(self.headerView.mas_bottom).offset(4);
make.width.mas_equalTo(self.nameLabel.contentLabel.width);
}];
if (model.cp_info != nil) {
self.cpDressView.hidden = NO;
self.cpCardView.hidden = NO;
self.cpDressView.model = model.cp_info;
self.cpCardView.model = model.cp_info;
[self.giftWallBtn mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(17);
make.right.mas_equalTo(-17);
make.height.mas_equalTo(ScaleWidth(40));
make.top.equalTo(self.cpCardView.mas_bottom).offset(8);
}];
}else{
self.cpDressView.hidden = YES;
self.cpCardView.hidden = YES;
[self.giftWallBtn mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(17);
make.right.mas_equalTo(-17);
make.height.mas_equalTo(ScaleWidth(40));
make.top.equalTo(self.whiteBgView.mas_bottom).offset(8);
}];
}
// self.tempName.text = model.nickname;
// [self.tempName.contentLabel sizeToFit];
// [self.tempName mas_remakeConstraints:^(MASConstraintMaker *make) {
// make.top.left.mas_equalTo(0);
// make.height.mas_equalTo(24);
// make.width.mas_equalTo(self.tempName.contentLabel.width);
// }];
// self.tempName.text = model.nickname;
// self.idLabel.text = [NSString stringWithFormat:@"ID:%@",model.user_code];
self.idLabel.text = [NSString stringWithFormat:@"%@|%ld岁 ID:%@",model.sex.intValue==1?QXText(@"男"):QXText(@"女"),[model.birthday ageWithDateOfBirth],model.user_code];
self.introduceLabel.text = model.profile; self.introduceLabel.text = model.profile;
[self.inCollectionView reloadData]; [self.inCollectionView reloadData];
[self.collectionView reloadData]; [self.collectionView reloadData];
@@ -299,17 +410,17 @@
} }
} }
if ([model.guild isExist]) { if ([model.guild isExist]) {
self.guildLabel.text = [NSString stringWithFormat:@"所属公会:%@",model.guild]; self.guildLabel.text = model.guild;
}else{ }else{
self.guildLabel.text = [NSString stringWithFormat:@"所属公会:%@",@"无"]; self.guildLabel.text = @"无";
} }
if (model.is_use_code.intValue == 1) { if (model.is_use_code.intValue == 1) {
self.useCodeImageView.hidden = NO; self.useCodeImageView.hidden = NO;
}else{ }else{
self.useCodeImageView.hidden = YES; self.useCodeImageView.hidden = YES;
} }
UIImage *sexImage = [UIImage imageNamed:model.sex.intValue==1?@"user_sex_boy":@"user_sex_girl"]; // UIImage *sexImage = [UIImage imageNamed:model.sex.intValue==1?@"user_sex_boy":@"user_sex_girl"];
self.sexImageView.image = sexImage; // self.sexImageView.image = sexImage;
} }
-(NSMutableArray *)tagArray{ -(NSMutableArray *)tagArray{

View File

@@ -0,0 +1,18 @@
//
// QXIntimateContentView.h
// QXLive
//
// Created by 启星 on 2025/11/21.
//
#import <UIKit/UIKit.h>
#import "JXPagerView.h"
NS_ASSUME_NONNULL_BEGIN
@interface QXIntimateContentView : UIView<JXPagerViewListViewDelegate>
@property (nonatomic,strong)NSString *userId;
@property (nonatomic, copy) void(^listScrollCallback)(UIScrollView *scrollView);
@property (nonatomic,assign)BOOL isTopFloating;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,311 @@
//
// QXIntimateContentView.m
// QXLive
//
// Created by on 2025/11/21.
//
#import "QXIntimateContentView.h"
#import "QXRoomBestFriendModel.h"
#import "QXMineNetwork.h"
#import "QXMoreIntimateViewController.h"
#import "QXButton.h"
#import "QXIntimateCpCell.h"
#import "QXIntimateNoCpCell.h"
#import "QXIntimateListCell.h"
#import "QXIntimateMoreListCell.h"
#import "QXUserCpCardView.h"
@interface QXIntimateContentView()<UITableViewDataSource,UITableViewDelegate>
@property (nonatomic,strong)UIView *tableHeaderView;
@property (nonatomic,strong)UIImageView *topImageView;
@property (nonatomic,strong)QXUserCpCardView *cpCardView;
@property (nonatomic,strong)UIView *noCpView;
@property (nonatomic,strong)UITableView *tableView;
@property (nonatomic,assign)NSInteger page;
@property (nonatomic,strong)NSMutableArray *dataArray;
@property (nonatomic,strong)QXRoomBestFriendModel *model;
@property (nonatomic, copy) void(^scrollCallback)(UIScrollView *scrollView);
@end
@implementation QXIntimateContentView
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self initSubviews];
}
return self;
}
-(void)initSubviews{
self.backgroundColor = RGB16(0xF5E8FF);
self.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.width, ScaleWidth(188))];
self.topImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"mine_intimate_top_bg"]];
self.topImageView.frame = CGRectMake(0, 0, self.width, ScaleWidth(241));
[self.tableHeaderView addSubview:self.topImageView];
[self.topImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.right.equalTo(self.tableHeaderView);
make.height.mas_equalTo(ScaleWidth(241));
}];
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"mine_intimate_title_bg"]];
UILabel *titleLabel = [[UILabel alloc] init];
titleLabel.font = [UIFont boldSystemFontOfSize:16];
titleLabel.textColor = RGB16(0xffffff);
titleLabel.text = @"心动";
[self.tableHeaderView addSubview:imageView];
[self.tableHeaderView addSubview:titleLabel];
[imageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.mas_equalTo(132);
make.height.mas_equalTo(36);
make.centerX.equalTo(self.tableHeaderView);
make.top.mas_equalTo(ScaleWidth(152));
}];
[titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(imageView);
make.centerY.equalTo(imageView).offset(2);
}];
self.cpCardView = [[QXUserCpCardView alloc] init];
self.cpCardView.hidden = YES;
[self.tableHeaderView addSubview:self.cpCardView];
[self.cpCardView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(imageView.mas_bottom).offset(16);
make.height.mas_equalTo(ScaleWidth(100));
make.left.mas_equalTo(24);
make.right.mas_equalTo(-24);
}];
self.noCpView = [[UIView alloc] init];
self.noCpView.hidden = YES;
[self.tableHeaderView addSubview:self.noCpView];
[self.noCpView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(24);
make.right.mas_equalTo(-24);
make.height.mas_equalTo(36);
make.top.equalTo(imageView.mas_bottom).offset(16);
}];
UIImageView *noCpImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"mine_intimate_no_cp_bg"]];
[self.noCpView addSubview:noCpImageView];
[noCpImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.noCpView);
}];
UILabel *noCpLabel = [[UILabel alloc] init];
noCpLabel.textAlignment = NSTextAlignmentCenter;
noCpLabel.font = [UIFont systemFontOfSize:12];
noCpLabel.text = @"暂无关系,前往房间互送特殊礼物达成关系吧";
noCpLabel.textColor = RGB16(0x624E79);
[self.noCpView addSubview:noCpLabel];
[noCpLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.noCpView);
}];
self.tableView.tableHeaderView = self.tableHeaderView;
[self addSubview:self.tableView];
}
-(void)layoutSubviews{
[super layoutSubviews];
self.tableView.frame = CGRectMake(0, 0, self.width, self.height);
}
-(void)setIsTopFloating:(BOOL)isTopFloating{
_isTopFloating = isTopFloating;
if (isTopFloating) {
[self addSubview:self.topImageView];
}else{
self.tableView.tableHeaderView = self.topImageView;
}
}
-(void)setUserId:(NSString *)userId{
_userId = userId;
self.page = 1;
[self getList];
}
-(void)getList{
MJWeakSelf
[QXMineNetwork userBestFriendsListWithUserId:self.userId page:self.page successBlock:^(QXRoomBestFriendModel * _Nonnull model) {
weakSelf.model = model;
if (model.cp == nil) {
self.noCpView.hidden = NO;
self.cpCardView.hidden = YES;
self.tableHeaderView.width = SCREEN_WIDTH;
self.tableHeaderView.height = ScaleWidth(188)+16+ScaleWidth(36);
}else{
self.noCpView.hidden = YES;
self.cpCardView.hidden = NO;
self.tableHeaderView.width = SCREEN_WIDTH;
self.tableHeaderView.height = ScaleWidth(188)+16+ScaleWidth(100);
self.cpCardView.model = model.cp;
}
if (weakSelf.page == 1) {
[weakSelf.dataArray removeAllObjects];
}
[weakSelf.dataArray addObjectsFromArray:model.no_cp];
[weakSelf.tableView reloadData];
if (model.no_cp.count == 0) {
weakSelf.tableView.mj_footer.state = MJRefreshStateNoMoreData;
}else{
[weakSelf.tableView.mj_footer endRefreshing];
}
[weakSelf.tableView.mj_header endRefreshing];
} failBlock:^(NSError * _Nonnull error, NSString * _Nonnull msg) {
}];
}
-(void)moreAction:(QXButton*)btn{
QXRoomBestFriendListModel *md = btn.object;
QXMoreIntimateViewController *vc = [[QXMoreIntimateViewController alloc] init];
vc.userId = self.userId;
vc.relation_id = md.relation_list.firstObject.relation_id;
[self.viewController.navigationController pushViewController:vc animated:YES];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return self.dataArray.count;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 1;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
QXRoomBestFriendListModel *md = self.dataArray[indexPath.section];
if (md.relation_list.count > 1) {
QXIntimateListCell*cell = [QXIntimateListCell cellWithTableView:tableView];
QXRoomBestFriendListModel *md = self.dataArray[indexPath.section];
cell.model = md;
return cell;
}else{
MJWeakSelf
QXIntimateMoreListCell *cell = [QXIntimateMoreListCell cellWithTableView:tableView];
cell.model = md.relation_list.firstObject;
cell.deleteSuccessBlock = ^(QXRelationshipListModel * _Nonnull model) {
weakSelf.page = 1;
[weakSelf getList];
};
return cell;
}
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.width, 50)];
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"mine_intimate_title_bg"]];
UILabel *titleLabel = [[UILabel alloc] init];
titleLabel.font = [UIFont boldSystemFontOfSize:16];
titleLabel.textColor = RGB16(0xffffff);
QXButton *btn = [[QXButton alloc] init];
[btn setTitle:@"更多>>" forState:(UIControlStateNormal)];
[btn setTitleColor:RGB16(0xE973FC) forState:(UIControlStateNormal)];
btn.titleLabel.font = [UIFont systemFontOfSize:12];
[btn addTarget:self action:@selector(moreAction:) forControlEvents:(UIControlEventTouchUpInside)];
[header addSubview:btn];
[header addSubview:imageView];
[header addSubview:titleLabel];
[imageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.mas_equalTo(132);
make.height.mas_equalTo(36);
make.centerX.centerY.equalTo(header);
}];
[titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(header);
make.centerY.equalTo(header).offset(2);
}];
[btn mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.mas_equalTo(-23);
make.top.bottom.equalTo(header);
make.width.mas_equalTo(40);
}];
QXRoomBestFriendListModel *md = self.dataArray[section];
titleLabel.text = md.relation_name;
if (md.relation_list.count>1) {
btn.hidden = NO;
btn.object = md;
}else{
btn.hidden = YES;
}
return header;
}
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
return 50;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
QXRoomBestFriendListModel *md = self.dataArray[indexPath.section];
if (md.relation_list.count > 1) {
return ScaleWidth(92)+18;
}else{
if (md.relation_list.count == 0) {
return 0;
}else{
return ScaleWidth(125);
}
}
}
-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{
UIView *footer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.width, 15)];
return footer;
}
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
return 15;
}
-(UITableView *)tableView{
if (!_tableView) {
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.width, self.height) style:(UITableViewStyleGrouped)];
_tableView.dataSource = self;
_tableView.delegate = self;
_tableView.backgroundColor = [UIColor clearColor];
_tableView.tableFooterView = [UIView new];
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
if (@available(iOS 15.0, *)) {
_tableView.sectionHeaderTopPadding = 0;
} else {
// Fallback on earlier versions
}
MJWeakSelf
_tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
weakSelf.page = 1;
[weakSelf getList];
}];
_tableView.mj_footer = [MJRefreshBackNormalFooter footerWithRefreshingBlock:^{
weakSelf.page++;
[weakSelf getList];
}];
}
return _tableView;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (self.scrollCallback != nil) {
self.scrollCallback(scrollView);
}
if (self.listScrollCallback != nil) {
self.listScrollCallback(scrollView);
}
}
#pragma mark - JXPagingViewListViewDelegate
- (UIScrollView *)listScrollView {
return self.tableView;
}
- (void)listViewDidScrollCallback:(void (^)(UIScrollView *))callback {
self.scrollCallback = callback;
}
- (UIView *)listView {
return self;
}
-(NSMutableArray *)dataArray{
if (!_dataArray) {
_dataArray = [NSMutableArray array];
}
return _dataArray;
}
@end

View File

@@ -0,0 +1,17 @@
//
// QXIntimateCpCell.h
// QXLive
//
// Created by 启星 on 2025/11/20.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface QXIntimateCpCell : UITableViewCell
@property (nonatomic,strong)QXUserCpInfoModel *model;
+(instancetype)cellWithTableView:(UITableView *)tableView;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,58 @@
//
// QXIntimateCpCell.m
// QXLive
//
// Created by on 2025/11/20.
//
#import "QXIntimateCpCell.h"
#import "QXUserCpCardView.h"
@interface QXIntimateCpCell()
@property (nonatomic,strong)QXUserCpCardView *cardView;
@end
@implementation QXIntimateCpCell
+(instancetype)cellWithTableView:(UITableView *)tableView{
static NSString *cellId = @"QXIntimateCpCell";
QXIntimateCpCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (!cell) {
cell = [[QXIntimateCpCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:cellId];
cell.backgroundColor = [UIColor clearColor];
}
return cell;
}
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
self.backgroundColor = [UIColor clearColor];
self.contentView.backgroundColor = [UIColor clearColor];
self.selectionStyle = UITableViewCellSelectionStyleNone;
[self initSubviews];
}
return self;
}
-(void)setModel:(QXUserCpInfoModel *)model{
_model = model;
self.cardView.model = model;
}
-(void)initSubviews{
self.cardView = [[QXUserCpCardView alloc] init];
[self.contentView addSubview:self.cardView];
[self.cardView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(24);
make.right.mas_equalTo(-24);
make.top.bottom.equalTo(self.contentView);
}];
}
- (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,17 @@
//
// QXIntimateListCell.h
// QXLive
//
// Created by 启星 on 2025/11/20.
//
#import <UIKit/UIKit.h>
#import "QXRoomBestFriendModel.h"
NS_ASSUME_NONNULL_BEGIN
@interface QXIntimateListCell : UITableViewCell
@property (nonatomic,strong)QXRoomBestFriendListModel *model;
+(instancetype)cellWithTableView:(UITableView *)tableView;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,85 @@
//
// QXIntimateListCell.m
// QXLive
//
// Created by on 2025/11/20.
//
#import "QXIntimateListCell.h"
#import "QXIntimateUserCell.h"
@interface QXIntimateListCell()<UICollectionViewDataSource,UICollectionViewDelegate>
@property (nonatomic,strong)UICollectionView *collectionView;
@end
@implementation QXIntimateListCell
+(instancetype)cellWithTableView:(UITableView *)tableView{
static NSString *cellId = @"QXIntimateListCell";
QXIntimateListCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (!cell) {
cell = [[QXIntimateListCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:cellId];
cell.backgroundColor = [UIColor clearColor];
}
return cell;
}
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
self.backgroundColor = [UIColor clearColor];
self.contentView.backgroundColor = [UIColor clearColor];
self.selectionStyle = UITableViewCellSelectionStyleNone;
[self initSubviews];
}
return self;
}
-(void)initSubviews{
NSInteger maxCount = 3;
NSInteger margin = 14;
CGFloat btnWith = (int)(SCREEN_WIDTH-48-14*2-1)/maxCount;
CGFloat btnHeight = ScaleWidth(125);
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.itemSize = CGSizeMake(btnWith, btnHeight);
layout.minimumLineSpacing = 0;
layout.minimumInteritemSpacing = 14;
layout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0);
layout.scrollDirection = UICollectionViewScrollDirectionVertical;
self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
[self.collectionView registerNib:[UINib nibWithNibName:@"QXIntimateUserCell" bundle:[NSBundle mainBundle]] forCellWithReuseIdentifier:@"QXIntimateUserCell"];
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
self.collectionView.showsHorizontalScrollIndicator = NO;
self.collectionView.bounces = NO;
self.collectionView.backgroundColor = UIColor.clearColor;
[self.contentView addSubview:self.collectionView];
[self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.bottom.equalTo(self.contentView);
make.left.mas_equalTo(24);
make.right.mas_equalTo(-24);
}];
}
-(void)setModel:(QXRoomBestFriendListModel *)model{
_model = model;
[self.collectionView reloadData];
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return self.model.relation_list.count;
}
-(__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
QXIntimateUserCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"QXIntimateUserCell" forIndexPath:indexPath];
cell.model = self.model.relation_list[indexPath.row];
return cell;
}
- (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,26 @@
//
// QXIntimateMoreListCell.h
// QXLive
//
// Created by 启星 on 2025/11/20.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface QXIntimateMoreListCell : UITableViewCell
@property (weak, nonatomic) IBOutlet QXSeatHeaderView *leftHeaderView;
@property (weak, nonatomic) IBOutlet UIImageView *leftSexImageView;
@property (weak, nonatomic) IBOutlet QXSeatHeaderView *rightHeaderView;
@property (weak, nonatomic) IBOutlet UIImageView *rightSexImageView;
@property (weak, nonatomic) IBOutlet UILabel *leftNameLabel;
@property (weak, nonatomic) IBOutlet UILabel *rightNameLabel;
@property (weak, nonatomic) IBOutlet UILabel *timeLabel;
@property (nonatomic,strong)QXRelationshipListModel *model;
@property (nonatomic,copy)void(^topSuccessBlock)(QXRelationshipListModel*model);
@property (nonatomic,copy)void(^deleteSuccessBlock)(QXRelationshipListModel*model);
+(instancetype)cellWithTableView:(UITableView *)tableView;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,106 @@
//
// QXIntimateMoreListCell.m
// QXLive
//
// Created by on 2025/11/20.
//
#import "QXIntimateMoreListCell.h"
#import "QXMineNetwork.h"
#import "QXCustomAlertView.h"
@interface QXIntimateMoreListCell()
@property (nonatomic,strong)QXCustomAlertView *alertView;
@end
@implementation QXIntimateMoreListCell
+(instancetype)cellWithTableView:(UITableView *)tableView{
static NSString *cellId = @"QXIntimateMoreListCell";
QXIntimateMoreListCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (!cell) {
cell = [[NSBundle mainBundle] loadNibNamed:cellId owner:nil options:nil].lastObject;
cell.backgroundColor = [UIColor clearColor];
cell.contentView.backgroundColor = [UIColor clearColor];
[cell.leftHeaderView addRoundedCornersWithRadius:25];
cell.leftHeaderView.layer.borderWidth = 2;
cell.leftHeaderView.layer.borderColor = RGB16(0xffffff).CGColor;
[cell.timeLabel addRoundedCornersWithRadius:9];
}
return cell;
}
- (IBAction)deleteAction:(id)sender {
MJWeakSelf
QXCustomAlertView *alertView = [[QXCustomAlertView alloc] init];
alertView.commitBlock = ^{
[weakSelf deleteRelation];
};
[alertView showInView:self.viewController.view title:@"您确定要解除本关系吗" message:[NSString stringWithFormat:@"解除关系需要%@金币",self.model.delete_me_coin] cancleTitle:@"取消" commitTitle:@"确定"];
}
- (IBAction)topAction:(id)sender {
MJWeakSelf
QXCustomAlertView *alertView = [[QXCustomAlertView alloc] init];
alertView.commitBlock = ^{
[weakSelf topRelation];
};
[alertView showInView:self.viewController.view title:@"您确定要置顶本关系吗" message:@"" cancleTitle:@"取消" commitTitle:@"确定"];
}
-(void)deleteRelation{
MJWeakSelf
[QXMineNetwork deleteRelationWithId:self.model.id successBlock:^(NSDictionary * _Nonnull dict) {
showToast(@"解除成功");
if (weakSelf.deleteSuccessBlock) {
weakSelf.deleteSuccessBlock(weakSelf.model);
}
} failBlock:^(NSError * _Nonnull error, NSString * _Nonnull msg) {
showToast(msg);
}];
}
-(void)topRelation{
MJWeakSelf
[QXMineNetwork topRelationWithId:self.model.id successBlock:^(NSDictionary * _Nonnull dict) {
showToast(@"置顶成功");
if (weakSelf.topSuccessBlock) {
weakSelf.topSuccessBlock(weakSelf.model);
}
} failBlock:^(NSError * _Nonnull error, NSString * _Nonnull msg) {
showToast(msg);
}];
}
-(void)setModel:(QXRelationshipListModel *)model{
_model = model;
if ([model.user_id1 isEqualToString:QXGlobal.shareGlobal.loginModel.user_id]) {
[self.leftHeaderView setHeadIcon:model.avatar2 dress:@""];
self.leftNameLabel.text = model.nickname2;
self.leftSexImageView.image = [UIImage imageNamed:model.sex2.intValue == 1?@"user_sex_boy":@"user_sex_girl"];
[self.rightHeaderView setHeadIcon:model.avatar1 dress:@""];
self.rightNameLabel.text = model.nickname1;
self.rightSexImageView.image = [UIImage imageNamed:model.sex1.intValue == 1?@"user_sex_boy":@"user_sex_girl"];
}else{
[self.leftHeaderView setHeadIcon:model.avatar1 dress:@""];
self.leftNameLabel.text = model.nickname1;
self.leftSexImageView.image = [UIImage imageNamed:model.sex1.intValue == 1?@"user_sex_boy":@"user_sex_girl"];
[self.rightHeaderView setHeadIcon:model.avatar2 dress:@""];
self.rightNameLabel.text = model.nickname2;
self.rightSexImageView.image = [UIImage imageNamed:model.sex2.intValue == 1?@"user_sex_boy":@"user_sex_girl"];
}
NSTimeInterval currentTime = [[NSDate date] timeIntervalSince1970];
long long milliseconds = (long long)(currentTime);
NSInteger time = model.end_time.longLongValue - milliseconds;
self.timeLabel.text = [NSString stringWithFormat:@" %@ ",[NSString getTimeWithSecond:time]];
}
- (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,163 @@
<?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="124" id="KGk-i7-Jjw" customClass="QXIntimateMoreListCell">
<rect key="frame" x="0.0" y="0.0" width="471" height="124"/>
<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="471" height="124"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="mine_intimate_more_list_bg" translatesAutoresizingMaskIntoConstraints="NO" id="hci-IM-egS">
<rect key="frame" x="24" y="8" width="423" height="108"/>
</imageView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9uF-c2-o0x">
<rect key="frame" x="24" y="8" width="423" height="108"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="pS6-S4-a2G" customClass="QXSeatHeaderView">
<rect key="frame" x="38" y="12" width="50" height="50"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="LoT-bN-kJj"/>
<constraint firstAttribute="width" constant="50" id="f4E-eT-Fu8"/>
</constraints>
</view>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="fJj-mx-2yM">
<rect key="frame" x="72" y="46" width="16" height="16"/>
<constraints>
<constraint firstAttribute="height" constant="16" id="7gA-dt-gle"/>
<constraint firstAttribute="width" constant="16" id="RCX-w6-Cz9"/>
</constraints>
</imageView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="50s-uU-EKD" customClass="QXSeatHeaderView">
<rect key="frame" x="335" y="12" width="50" height="50"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="EF7-Lz-yqY"/>
<constraint firstAttribute="width" constant="50" id="nBJ-dS-O67"/>
</constraints>
</view>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="6nc-bo-ejr">
<rect key="frame" x="369" y="46" width="16" height="16"/>
<constraints>
<constraint firstAttribute="width" constant="16" id="TNB-gm-KC7"/>
<constraint firstAttribute="height" constant="16" id="chW-7w-4Pp"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="关系天数" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dAK-uZ-bVb">
<rect key="frame" x="185.66666666666666" y="24" width="52" height="15"/>
<constraints>
<constraint firstAttribute="height" constant="15" id="xMo-2K-KLg"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.71764705882352942" green="0.48627450980392156" blue="0.85490196078431369" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" 99天23小时 " textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8wc-ZY-rQa">
<rect key="frame" x="166" y="44" width="91" height="18"/>
<color key="backgroundColor" red="0.83529411764705885" green="0.59607843137254901" blue="0.97647058823529409" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="18" id="hqK-kl-k7t"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eAs-09-73J">
<rect key="frame" x="46.666666666666671" y="66" width="33" height="16"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.36078431372549019" green="0.16470588235294117" blue="0.44313725490196076" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tuv-zg-sBW">
<rect key="frame" x="343.66666666666669" y="66" width="33" height="16"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.36078431372549019" green="0.16470588235294117" blue="0.44313725490196076" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstItem="50s-uU-EKD" firstAttribute="centerY" secondItem="pS6-S4-a2G" secondAttribute="centerY" id="5g4-vp-EYv"/>
<constraint firstItem="8wc-ZY-rQa" firstAttribute="top" secondItem="dAK-uZ-bVb" secondAttribute="bottom" constant="5" id="8rk-dg-kaQ"/>
<constraint firstItem="fJj-mx-2yM" firstAttribute="trailing" secondItem="pS6-S4-a2G" secondAttribute="trailing" id="BEj-jg-gAB"/>
<constraint firstItem="dAK-uZ-bVb" firstAttribute="top" secondItem="9uF-c2-o0x" secondAttribute="top" constant="24" id="D9p-BA-KBw"/>
<constraint firstItem="6nc-bo-ejr" firstAttribute="bottom" secondItem="50s-uU-EKD" secondAttribute="bottom" id="FGe-n1-Wks"/>
<constraint firstItem="pS6-S4-a2G" firstAttribute="leading" secondItem="9uF-c2-o0x" secondAttribute="leading" constant="38" id="H5c-Mz-Qma"/>
<constraint firstItem="dAK-uZ-bVb" firstAttribute="centerX" secondItem="9uF-c2-o0x" secondAttribute="centerX" id="VG0-8q-Lrq"/>
<constraint firstAttribute="trailing" secondItem="50s-uU-EKD" secondAttribute="trailing" constant="38" id="Wh8-QI-j4t"/>
<constraint firstItem="pS6-S4-a2G" firstAttribute="top" secondItem="9uF-c2-o0x" secondAttribute="top" constant="12" id="YtX-oa-Z5o"/>
<constraint firstItem="fJj-mx-2yM" firstAttribute="bottom" secondItem="pS6-S4-a2G" secondAttribute="bottom" id="a5l-4I-UsC"/>
<constraint firstItem="tuv-zg-sBW" firstAttribute="centerX" secondItem="50s-uU-EKD" secondAttribute="centerX" id="eA4-hx-xId"/>
<constraint firstItem="eAs-09-73J" firstAttribute="top" secondItem="pS6-S4-a2G" secondAttribute="bottom" constant="4" id="inp-kG-exH"/>
<constraint firstItem="6nc-bo-ejr" firstAttribute="trailing" secondItem="50s-uU-EKD" secondAttribute="trailing" id="j7A-eO-KSJ"/>
<constraint firstItem="eAs-09-73J" firstAttribute="centerX" secondItem="pS6-S4-a2G" secondAttribute="centerX" id="smC-jH-4iI"/>
<constraint firstItem="8wc-ZY-rQa" firstAttribute="centerX" secondItem="9uF-c2-o0x" secondAttribute="centerX" id="uKd-PA-s9w"/>
<constraint firstItem="tuv-zg-sBW" firstAttribute="top" secondItem="50s-uU-EKD" secondAttribute="bottom" constant="4" id="yjp-7F-Gwe"/>
</constraints>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="52j-r4-V3h">
<rect key="frame" x="407" y="8" width="40" height="40"/>
<constraints>
<constraint firstAttribute="height" constant="40" id="DJm-rA-Osg"/>
<constraint firstAttribute="width" constant="40" id="ZfL-xo-Y79"/>
</constraints>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" image="mine_intimate_delete"/>
<connections>
<action selector="deleteAction:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="u9N-6h-ln1"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="QZV-rH-5ej">
<rect key="frame" x="407" y="76" width="40" height="40"/>
<constraints>
<constraint firstAttribute="height" constant="40" id="TvY-5A-Fdl"/>
<constraint firstAttribute="width" constant="40" id="eNA-hq-dP6"/>
</constraints>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" image="mine_intimate_top"/>
<connections>
<action selector="topAction:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="HXq-Vs-0Uo"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="hci-IM-egS" firstAttribute="trailing" secondItem="9uF-c2-o0x" secondAttribute="trailing" id="5HX-ef-Aru"/>
<constraint firstAttribute="trailing" secondItem="hci-IM-egS" secondAttribute="trailing" constant="24" id="7jP-Cm-6si"/>
<constraint firstItem="9uF-c2-o0x" firstAttribute="top" secondItem="hci-IM-egS" secondAttribute="top" id="8mD-1d-i7u"/>
<constraint firstItem="9uF-c2-o0x" firstAttribute="bottom" secondItem="hci-IM-egS" secondAttribute="bottom" id="LrA-c5-Zoh"/>
<constraint firstItem="52j-r4-V3h" firstAttribute="top" secondItem="hci-IM-egS" secondAttribute="top" id="P3d-an-1db"/>
<constraint firstItem="hci-IM-egS" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="24" id="Ymq-yb-K6H"/>
<constraint firstAttribute="bottom" secondItem="hci-IM-egS" secondAttribute="bottom" constant="8" id="iC3-iC-x1t"/>
<constraint firstItem="9uF-c2-o0x" firstAttribute="leading" secondItem="hci-IM-egS" secondAttribute="leading" id="kpi-KG-o7o"/>
<constraint firstItem="QZV-rH-5ej" firstAttribute="trailing" secondItem="hci-IM-egS" secondAttribute="trailing" id="mAY-OL-7IZ"/>
<constraint firstItem="hci-IM-egS" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="8" id="yGQ-rj-f2D"/>
<constraint firstItem="52j-r4-V3h" firstAttribute="trailing" secondItem="hci-IM-egS" secondAttribute="trailing" id="ylJ-H9-c4E"/>
<constraint firstItem="QZV-rH-5ej" firstAttribute="bottom" secondItem="hci-IM-egS" secondAttribute="bottom" id="yny-Nc-k10"/>
</constraints>
</tableViewCellContentView>
<viewLayoutGuide key="safeArea" id="aW0-zy-SZf"/>
<connections>
<outlet property="leftHeaderView" destination="pS6-S4-a2G" id="pIO-eN-du1"/>
<outlet property="leftNameLabel" destination="eAs-09-73J" id="3xn-sG-6Nz"/>
<outlet property="leftSexImageView" destination="fJj-mx-2yM" id="TSa-Nv-4tO"/>
<outlet property="rightHeaderView" destination="50s-uU-EKD" id="39P-NK-IhC"/>
<outlet property="rightNameLabel" destination="tuv-zg-sBW" id="unH-ct-gfv"/>
<outlet property="rightSexImageView" destination="6nc-bo-ejr" id="Xv0-nC-Nhq"/>
<outlet property="timeLabel" destination="8wc-ZY-rQa" id="BIS-Ab-0EB"/>
</connections>
<point key="canvasLocation" x="252.67175572519082" y="47.887323943661976"/>
</tableViewCell>
</objects>
<resources>
<image name="mine_intimate_delete" width="20" height="20"/>
<image name="mine_intimate_more_list_bg" width="327" height="92"/>
<image name="mine_intimate_top" width="20" height="20"/>
</resources>
</document>

View File

@@ -0,0 +1,16 @@
//
// QXIntimateNoCpCell.h
// QXLive
//
// Created by 启星 on 2025/11/20.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface QXIntimateNoCpCell : UITableViewCell
+(instancetype)cellWithTableView:(UITableView *)tableView;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,32 @@
//
// QXIntimateNoCpCell.m
// QXLive
//
// Created by on 2025/11/20.
//
#import "QXIntimateNoCpCell.h"
@implementation QXIntimateNoCpCell
+(instancetype)cellWithTableView:(UITableView *)tableView{
static NSString *cellId = @"QXIntimateNoCpCell";
QXIntimateNoCpCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (!cell) {
cell = [[NSBundle mainBundle] loadNibNamed:cellId owner:nil options:nil].lastObject;
cell.backgroundColor = [UIColor clearColor];
cell.contentView.backgroundColor = [UIColor clearColor];
}
return cell;
}
- (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,48 @@
<?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="44" id="KGk-i7-Jjw" customClass="QXIntimateNoCpCell">
<rect key="frame" x="0.0" y="0.0" width="411" height="44"/>
<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="411" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="mine_intimate_no_cp_bg" translatesAutoresizingMaskIntoConstraints="NO" id="t41-tz-mj8">
<rect key="frame" x="24" y="0.0" width="363" height="44"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="暂无关系,前往房间互送特殊礼物达成关系吧" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iye-nq-Z28">
<rect key="frame" x="24" y="0.0" width="363" height="44"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.38431372549019605" green="0.30588235294117649" blue="0.47450980392156861" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstItem="iye-nq-Z28" firstAttribute="leading" secondItem="t41-tz-mj8" secondAttribute="leading" id="0kT-Io-iA2"/>
<constraint firstItem="iye-nq-Z28" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="5K8-Fy-YQy"/>
<constraint firstItem="iye-nq-Z28" firstAttribute="trailing" secondItem="t41-tz-mj8" secondAttribute="trailing" id="J5K-Sd-cnV"/>
<constraint firstAttribute="trailing" secondItem="t41-tz-mj8" secondAttribute="trailing" constant="24" id="NDJ-oT-B5A"/>
<constraint firstAttribute="bottom" secondItem="t41-tz-mj8" secondAttribute="bottom" id="Uk6-zs-yKM"/>
<constraint firstItem="t41-tz-mj8" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="24" id="hEY-SF-CcT"/>
<constraint firstAttribute="bottom" secondItem="iye-nq-Z28" secondAttribute="bottom" id="kmA-fO-sQG"/>
<constraint firstItem="t41-tz-mj8" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="vRB-xP-aoe"/>
</constraints>
</tableViewCellContentView>
<viewLayoutGuide key="safeArea" id="aW0-zy-SZf"/>
<point key="canvasLocation" x="208.3969465648855" y="19.718309859154932"/>
</tableViewCell>
</objects>
<resources>
<image name="mine_intimate_no_cp_bg" width="328" height="36"/>
</resources>
</document>

View File

@@ -0,0 +1,20 @@
//
// QXIntimateUserCell.h
// QXLive
//
// Created by 启星 on 2025/11/20.
//
#import <UIKit/UIKit.h>
#import "QXRoomFriendRelationModel.h"
NS_ASSUME_NONNULL_BEGIN
@interface QXIntimateUserCell : UICollectionViewCell
@property (weak, nonatomic) IBOutlet UILabel *timeLabel;
@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
@property (weak, nonatomic) IBOutlet QXSeatHeaderView *headerView;
@property (weak, nonatomic) IBOutlet UIImageView *sexImageView;
@property (nonatomic,strong)QXRelationshipListModel *model;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,32 @@
//
// QXIntimateUserCell.m
// QXLive
//
// Created by on 2025/11/20.
//
#import "QXIntimateUserCell.h"
@implementation QXIntimateUserCell
-(void)setModel:(QXRelationshipListModel *)model{
_model = model;
if ([model.user_id1 isEqualToString:QXGlobal.shareGlobal.loginModel.user_id]) {
[self.headerView setHeadIcon:model.avatar2 dress:@""];
self.nameLabel.text = model.nickname2;
self.sexImageView.image = [UIImage imageNamed:model.sex2.intValue == 1?@"user_sex_boy":@"user_sex_girl"];
}else{
[self.headerView setHeadIcon:model.avatar1 dress:@""];
self.nameLabel.text = model.nickname1;
self.sexImageView.image = [UIImage imageNamed:model.sex1.intValue == 1?@"user_sex_boy":@"user_sex_girl"];
}
self.timeLabel.text = [NSString getTimeWithSecond:model.end_time.longLongValue];
}
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
self.backgroundColor = [UIColor clearColor];
self.contentView.backgroundColor = [UIColor clearColor];
}
@end

View File

@@ -0,0 +1,94 @@
<?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"/>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="gTV-IL-0wX" customClass="QXIntimateUserCell">
<rect key="frame" x="0.0" y="0.0" width="100" height="125"/>
<autoresizingMask key="autoresizingMask"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="100" height="125"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="mine_intimate_user_bg" translatesAutoresizingMaskIntoConstraints="NO" id="txM-5U-EHB">
<rect key="frame" x="0.0" y="0.0" width="100" height="125"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="0天" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dho-1D-FyV">
<rect key="frame" x="38.666666666666664" y="0.0" width="22.666666666666664" height="20"/>
<constraints>
<constraint firstAttribute="height" constant="20" id="gdb-Xo-kaB"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="mine_intimate_user_header_bg" translatesAutoresizingMaskIntoConstraints="NO" id="hw4-Xa-702">
<rect key="frame" x="18" y="25" width="64" height="64"/>
<constraints>
<constraint firstAttribute="height" constant="64" id="1pU-lU-na7"/>
<constraint firstAttribute="width" constant="64" id="Jdy-UJ-3T8"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="张三" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Q6K-WV-PC5">
<rect key="frame" x="0.0" y="96" width="100" height="15"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" red="0.38431372549019605" green="0.30588235294117649" blue="0.47450980392156861" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Qh2-8T-GlR" customClass="QXSeatHeaderView">
<rect key="frame" x="28" y="35" width="44" height="44"/>
<constraints>
<constraint firstAttribute="width" constant="44" id="NrD-gX-5TA"/>
<constraint firstAttribute="height" constant="44" id="pW7-XR-Skb"/>
</constraints>
</view>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="user_sex_boy" translatesAutoresizingMaskIntoConstraints="NO" id="1bD-2w-qbH">
<rect key="frame" x="66" y="25" width="16" height="16"/>
<constraints>
<constraint firstAttribute="height" constant="16" id="8wn-Nx-cEd"/>
<constraint firstAttribute="width" constant="16" id="dDj-4G-phe"/>
</constraints>
</imageView>
</subviews>
</view>
<viewLayoutGuide key="safeArea" id="SEy-5g-ep8"/>
<constraints>
<constraint firstItem="hw4-Xa-702" firstAttribute="centerX" secondItem="SEy-5g-ep8" secondAttribute="centerX" id="5i1-sT-3Zj"/>
<constraint firstItem="Qh2-8T-GlR" firstAttribute="centerY" secondItem="hw4-Xa-702" secondAttribute="centerY" id="AvG-Nv-TNa"/>
<constraint firstItem="Qh2-8T-GlR" firstAttribute="centerX" secondItem="hw4-Xa-702" secondAttribute="centerX" id="JPf-mm-Jc9"/>
<constraint firstItem="txM-5U-EHB" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" id="L4c-PK-Xqp"/>
<constraint firstAttribute="bottom" secondItem="txM-5U-EHB" secondAttribute="bottom" id="Pbc-2E-uSt"/>
<constraint firstAttribute="trailing" secondItem="Q6K-WV-PC5" secondAttribute="trailing" id="QaU-xI-4sD"/>
<constraint firstItem="dho-1D-FyV" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" id="Ubc-jE-65g"/>
<constraint firstItem="1bD-2w-qbH" firstAttribute="trailing" secondItem="hw4-Xa-702" secondAttribute="trailing" id="Xat-ix-aRx"/>
<constraint firstItem="Q6K-WV-PC5" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" id="ilF-pE-WHB"/>
<constraint firstAttribute="trailing" secondItem="txM-5U-EHB" secondAttribute="trailing" id="q1U-tP-oND"/>
<constraint firstItem="hw4-Xa-702" firstAttribute="top" secondItem="dho-1D-FyV" secondAttribute="bottom" constant="5" id="qxe-fx-tf0"/>
<constraint firstItem="txM-5U-EHB" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" id="s2x-GV-Zhe"/>
<constraint firstItem="1bD-2w-qbH" firstAttribute="top" secondItem="hw4-Xa-702" secondAttribute="top" id="wix-kL-ORM"/>
<constraint firstItem="dho-1D-FyV" firstAttribute="centerX" secondItem="SEy-5g-ep8" secondAttribute="centerX" id="wp9-JV-Kt1"/>
<constraint firstItem="Q6K-WV-PC5" firstAttribute="top" secondItem="hw4-Xa-702" secondAttribute="bottom" constant="7" id="xUO-yb-6iS"/>
</constraints>
<size key="customSize" width="202" height="287"/>
<connections>
<outlet property="headerView" destination="Qh2-8T-GlR" id="6ll-ny-kbj"/>
<outlet property="nameLabel" destination="Q6K-WV-PC5" id="PLa-Qa-VN9"/>
<outlet property="sexImageView" destination="1bD-2w-qbH" id="gZq-iz-Pnr"/>
<outlet property="timeLabel" destination="dho-1D-FyV" id="Tj1-Re-Cpy"/>
</connections>
<point key="canvasLocation" x="254.96183206106869" y="103.16901408450705"/>
</collectionViewCell>
</objects>
<resources>
<image name="mine_intimate_user_bg" width="100" height="125"/>
<image name="mine_intimate_user_header_bg" width="64" height="64"/>
<image name="user_sex_boy" width="32" height="32"/>
</resources>
</document>

View File

@@ -0,0 +1,25 @@
//
// QXMineAddSongGiftView.h
// QXLive
//
// Created by 启星 on 2025/11/13.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@protocol QXMineAddSongGiftViewDelegate <NSObject>
@optional
-(void)didSeletedGift:(QXGiftModel*)giftModel giftCount:(NSString*)giftCount;
@end
@interface QXMineAddSongGiftView : UIView
@property (nonatomic,weak)id<QXMineAddSongGiftViewDelegate>delegate;
-(void)showInView:(UIView *)view;
-(void)hide;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,200 @@
//
// QXMineAddSongGiftView.m
// QXLive
//
// Created by on 2025/11/13.
//
#import "QXMineAddSongGiftView.h"
#import "QXGiftCell.h"
#import "QXMineNetwork.h"
#import "QXMenuPopView.h"
@interface QXMineAddSongGiftView()<UICollectionViewDelegate,UICollectionViewDataSource,UIGestureRecognizerDelegate,QXMenuPopViewDelegate>
@property (nonatomic,strong)UIView *bgView;
@property (nonatomic,strong)UIImageView *bgImageView;
@property (nonatomic,strong)UICollectionView *collectionView;
@property (nonatomic,strong)NSMutableArray *dataArray;
@property (nonatomic,assign)NSInteger selectedIndex;
@property (nonatomic,strong)QXGiftModel *model;
@property (nonatomic,strong)UIView *sendBgView;
@property (nonatomic,strong)UIButton *countBtn;
@property (nonatomic,strong)UIButton *sendBtn;
@property (nonatomic,strong)UIButton *sendAllBtn;
@property (nonatomic,strong)NSString* giftCount;
@end
@implementation QXMineAddSongGiftView
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self initSubviews];
}
return self;
}
-(void)initSubviews{
self.giftCount = @"1";
self.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.3];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hide)];
tap.delegate = self;
[self addGestureRecognizer:tap];
self.bgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, ScaleWidth(429)+kSafeAreaBottom)];
[self.bgView addRoundedCornersWithRadius:16 byRoundingCorners:(UIRectCornerTopLeft|UIRectCornerTopRight)];
[self addSubview:self.bgView];
self.bgImageView = [[UIImageView alloc] initWithFrame:self.bounds];
self.bgImageView.image = [UIImage imageNamed:@"room_sound_bg"];
[self.bgView addSubview:self.bgImageView];
self.selectedIndex = -1;
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.itemSize = CGSizeMake((SCREEN_WIDTH-16*2-12*3)/4, ScaleWidth(119));
layout.minimumLineSpacing = 12;
layout.minimumInteritemSpacing = 12;
layout.sectionInset = UIEdgeInsetsMake(0, 16, 0, 16);
layout.scrollDirection = UICollectionViewScrollDirectionVertical;
self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 16, self.width, self.bgView.height-12) collectionViewLayout:layout];
[self.collectionView registerNib:[UINib nibWithNibName:@"QXGiftCell" bundle:[NSBundle mainBundle]] forCellWithReuseIdentifier:@"QXGiftCell"];
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
self.collectionView.showsHorizontalScrollIndicator = NO;
self.collectionView.bounces = NO;
self.collectionView.backgroundColor = [UIColor clearColor];
[self.bgView addSubview:self.collectionView];
self.sendBgView = [[UIView alloc] init];
[self.sendBgView addRoundedCornersWithRadius:17.5];
self.sendBgView.layer.borderColor = QXConfig.themeColor.CGColor;
self.sendBgView.layer.borderWidth = 1;
[self.bgView addSubview:self.sendBgView];
[self.sendBgView mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.mas_equalTo(-16);
make.width.mas_equalTo(120);
make.height.mas_equalTo(35);
make.bottom.mas_equalTo(-kSafeAreaBottom-12);
}];
self.countBtn = [[UIButton alloc] init];
[self.countBtn setTitle:@"X1" forState:(UIControlStateNormal)];
[self.countBtn setTitleColor:RGB16(0xffffff) forState:(UIControlStateNormal)];
self.countBtn.titleLabel.font = [UIFont systemFontOfSize:12];
[self.countBtn addTarget:self action:@selector(selectedCount:) forControlEvents:(UIControlEventTouchUpInside)];
[self.sendBgView addSubview:self.countBtn];
[self.countBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.bottom.equalTo(self.sendBgView);
make.width.equalTo(self.sendBgView.mas_width).multipliedBy(0.5);
}];
self.sendBtn = [[UIButton alloc] init];
[self.sendBtn setTitle:QXText(@"确定") forState:(UIControlStateNormal)];
[self.sendBtn setTitleColor:QXConfig.btnTextColor forState:(UIControlStateNormal)];
self.sendBtn.backgroundColor = QXConfig.themeColor;
self.sendBtn.titleLabel.font = [UIFont systemFontOfSize:12];
[self.sendBtn addTarget:self action:@selector(sendAction) forControlEvents:(UIControlEventTouchUpInside)];
[self.sendBgView addSubview:self.sendBtn];
[self.sendBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.top.bottom.equalTo(self.sendBgView);
make.width.equalTo(self.sendBgView.mas_width).multipliedBy(0.5);
}];
[self getGiftList];
}
-(void)didSelectedIndex:(NSInteger)index menuTitle:(NSString *)menuTitle{
[self.countBtn setTitle:menuTitle forState:(UIControlStateNormal)];
NSCharacterSet* nonDigits =[[NSCharacterSet decimalDigitCharacterSet] invertedSet];
NSInteger count =[[menuTitle stringByTrimmingCharactersInSet:nonDigits] integerValue];
QXLOG(@"选择了%ld个",count);
self.giftCount = [NSString stringWithFormat:@"%ld",count];
}
-(void)selectedCount:(UIButton*)sender{
QXMenuPopView *popView = [[QXMenuPopView alloc] initWithPoint:CGPointMake(SCREEN_WIDTH-16-60-30, SCREEN_HEIGHT-kSafeAreaBottom-50-225) width:88 height:225];
popView.type = QXMenuPopViewTypeArrowBottom;
popView.dataArray = @[@"X20",@"X15",@"X10",@"X5",@"X1"];
popView.delegate = self;
[popView showInView:KEYWINDOW];
}
-(void)sendAction{
if (self.model == nil) {
showToast(@"请选择礼物");
return;
}
if (self.delegate && [self.delegate respondsToSelector:@selector(didSeletedGift:giftCount:)]) {
[self.delegate didSeletedGift:self.model giftCount:self.giftCount];
}
[self hide];
}
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
return touch.view == self;
}
-(void)showInView:(UIView *)view{
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];
}];
}
-(void)getGiftList{
MJWeakSelf
[QXMineNetwork giftListWithLabel:@"1" roomId:@"" successBlock:^(NSArray<QXGiftModel *> * _Nonnull list) {
[weakSelf.dataArray removeAllObjects];
[weakSelf.dataArray addObjectsFromArray:list];
[weakSelf.collectionView reloadData];
} failBlock:^(NSError * _Nonnull error, NSString * _Nonnull msg) {
}];
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return self.dataArray.count;
}
-(__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
QXGiftCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"QXGiftCell" forIndexPath:indexPath];
cell.cellType = QXGiftCellTypeLive;
cell.roomGiftModel = self.dataArray[indexPath.row];
if (self.selectedIndex == indexPath.row) {
cell.selecteBtn.selected = YES;
cell.giftNameLabel.textColor = RGB16(0x333333);
[cell.cornBtn setTitleColor:RGB16(0x333333) forState:(UIControlStateNormal)];
}else{
cell.selecteBtn.selected = NO;
cell.giftNameLabel.textColor = RGB16(0xffffff);
[cell.cornBtn setTitleColor:RGB16(0xffffff) forState:(UIControlStateNormal)];
}
return cell;
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row == self.selectedIndex) {
return;
}
self.selectedIndex = indexPath.row;
self.model = self.dataArray[indexPath.row];
[collectionView reloadData];
}
-(NSMutableArray *)dataArray{
if (!_dataArray) {
_dataArray = [NSMutableArray array] ;
}
return _dataArray;
}
@end

View File

@@ -0,0 +1,34 @@
//
// QXMineAddSongView.h
// QXLive
//
// Created by 启星 on 2025/11/13.
//
#import <UIKit/UIKit.h>
#import "QXUserSongListModel.h"
NS_ASSUME_NONNULL_BEGIN
@protocol QXMineAddSongViewDelegate <NSObject>
@optional
-(void)qx_mineAddSongViewCommitWithSongName:(NSString*)songName giftModel:(QXGiftModel*)giftModel;
-(void)qx_mineEditSongViewCommitWithSongModel:(QXUserSongListModel*)songModel;
-(void)qx_mineAddSongViewDidSeleteGift;
-(void)qx_mineAddSongViewDidRemove;
@end
@interface QXMineAddSongView : UIView
@property (nonatomic,strong)QXGiftModel *giftModel;
@property (nonatomic,strong)QXUserSongListModel *songModel;
@property (nonatomic,weak)id<QXMineAddSongViewDelegate>delegate;
-(void)showInView:(UIView *)view;
-(void)hide;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,234 @@
//
// QXMineAddSongView.m
// QXLive
//
// Created by on 2025/11/13.
//
#import "QXMineAddSongView.h"
@interface QXMineAddSongView()<UITextFieldDelegate>
@property (nonatomic,strong)UIView *bgView;
@property (nonatomic,strong)UILabel *titleLabel;
@property (nonatomic,strong)UIButton *closeBtn;
@property (nonatomic,strong)UIView *songContenView;
@property (nonatomic,strong)UITextField *songTextField;
@property (nonatomic,strong)UIView *giftContenView;
@property (nonatomic,strong)UILabel *giftLabel;
@property (nonatomic,strong)UIImageView *giftArrow;
@property (nonatomic,strong)UIButton *giftBtn;
@property (nonatomic,strong)UIButton *cancelBtn;
@property (nonatomic,strong)UIButton *commitBtn;
@end
@implementation QXMineAddSongView
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self initSubviews];
}
return self;
}
-(void)setGiftModel:(QXGiftModel *)giftModel{
_giftModel = giftModel;
self.giftLabel.text = [NSString stringWithFormat:@"%@x%@",giftModel.gift_name,giftModel.num];
if (self.songModel) {
self.songModel.gift_num = giftModel.num;
self.songModel.gift_id = giftModel.gift_id;
}
}
-(void)setSongModel:(QXUserSongListModel *)songModel{
_songModel = songModel;
self.giftLabel.text = [NSString stringWithFormat:@"%@x%@",songModel.gift_name,songModel.gift_num];
self.songTextField.text = songModel.song_name;
}
-(void)initSubviews{
self.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.3];
self.bgView = [[UIView alloc] initWithFrame:CGRectMake((SCREEN_WIDTH-ScaleWidth(275))/2, 0, ScaleWidth(275), 300)];
self.bgView.backgroundColor = RGB16(0xffffff);
[self.bgView addRoundedCornersWithRadius:16];
[self addSubview:self.bgView];
self.titleLabel = [[UILabel alloc] init];
self.titleLabel.text = @"新增歌单";
self.titleLabel.font = [UIFont boldSystemFontOfSize:16];
self.titleLabel.textColor = QXConfig.textColor;
[self.bgView addSubview:self.titleLabel];
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.bgView);
make.top.equalTo(self.bgView).offset(12);
make.height.mas_equalTo(24);
}];
self.closeBtn = [[UIButton alloc] init];
[self.closeBtn setImage:[UIImage imageNamed:@"wallet_close"] forState:(UIControlStateNormal)];
[self.closeBtn addTarget:self action:@selector(hide) forControlEvents:(UIControlEventTouchUpInside)];
[self.bgView addSubview:self.closeBtn];
[self.closeBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.bgView);
make.height.width.mas_equalTo(40);
make.centerY.equalTo(self.titleLabel);
}];
self.songContenView = [[UIView alloc] init];
[self.songContenView addRoundedCornersWithRadius:11];
self.songContenView.backgroundColor = RGB16(0xEFF2F8);
[self.bgView addSubview:self.songContenView];
[self.songContenView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(10);
make.right.mas_equalTo(-10);
make.height.mas_equalTo(41);
make.top.equalTo(self.titleLabel.mas_bottom).offset(36);
}];
self.songTextField = [[UITextField alloc] init];
self.songTextField.font = [UIFont systemFontOfSize:16];
self.songTextField.textColor = RGB16(0x9B9B9B);
self.songTextField.delegate = self;
self.songTextField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"请输入歌曲名称" attributes:@{NSForegroundColorAttributeName:RGB16(0x9B9B9B)}];
[self.songContenView addSubview:self.songTextField];
[self.songTextField mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(12);
make.right.mas_equalTo(-12);
make.top.bottom.equalTo(self.songContenView);
}];
self.giftContenView = [[UIView alloc] init];
[self.giftContenView addRoundedCornersWithRadius:11];
self.giftContenView.backgroundColor = RGB16(0xEFF2F8);
[self.bgView addSubview:self.giftContenView];
[self.giftContenView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(10);
make.right.mas_equalTo(-10);
make.height.mas_equalTo(41);
make.top.equalTo(self.songContenView.mas_bottom).offset(24);
}];
self.giftArrow = [[UIImageView alloc] initWithImage:[[UIImage imageNamed:@"arrowRight"] imageByTintColor:RGB16(0x9B9B9B)]];
[self.giftContenView addSubview:self.giftArrow];
[self.giftArrow mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.mas_equalTo(-12);
make.width.height.mas_equalTo(24);
make.centerY.equalTo(self.giftContenView);
}];
self.giftLabel = [[UILabel alloc] init];
self.giftLabel.text = @"请选择礼物";
self.giftLabel.font = [UIFont systemFontOfSize:16];
self.giftLabel.textColor = RGB16(0x9B9B9B);
[self.giftContenView addSubview:self.giftLabel];
[self.giftLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(12);
make.right.equalTo(self.giftArrow.mas_left).offset(-12);
make.top.bottom.equalTo(self.giftContenView);
}];
self.giftBtn = [[UIButton alloc] init];
[self.giftBtn addTarget:self action:@selector(giftAction) forControlEvents:(UIControlEventTouchUpInside)];
[self.giftContenView addSubview:self.giftBtn];
[self.giftBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.giftContenView);
}];
self.cancelBtn = [[UIButton alloc] init];
[self.bgView addSubview:self.cancelBtn];
[self.cancelBtn setTitle:@"取消" forState:(UIControlStateNormal)];
[self.cancelBtn addTarget:self action:@selector(hide) forControlEvents:(UIControlEventTouchUpInside)];
[self.cancelBtn setTitleColor:RGB16(0x999999) forState:(UIControlStateNormal)];
self.cancelBtn.titleLabel.font = [UIFont systemFontOfSize:14];
self.cancelBtn.backgroundColor = RGB16(0xF3F3F3);
[self.cancelBtn addRoundedCornersWithRadius:21];
[self.cancelBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(19);
make.width.mas_equalTo(110);
make.height.mas_equalTo(42);
make.bottom.mas_equalTo(-20);
}];
self.commitBtn = [[UIButton alloc] init];
[self.bgView addSubview:self.commitBtn];
[self.commitBtn setTitle:@"确认" forState:(UIControlStateNormal)];
[self.commitBtn setTitleColor:RGB16(0xffffff) forState:(UIControlStateNormal)];
[self.commitBtn addTarget:self action:@selector(commitAction) forControlEvents:(UIControlEventTouchUpInside)];
self.commitBtn.titleLabel.font = [UIFont systemFontOfSize:14];
self.commitBtn.backgroundColor = QXConfig.themeColor;
[self.commitBtn addRoundedCornersWithRadius:21];
[self.commitBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.mas_equalTo(-19);
make.width.mas_equalTo(110);
make.height.mas_equalTo(42);
make.bottom.mas_equalTo(-20);
}];
}
-(void)giftAction{
if (self.delegate && [self.delegate respondsToSelector:@selector(qx_mineAddSongViewDidSeleteGift)]) {
[self.delegate qx_mineAddSongViewDidSeleteGift];
}
}
-(void)commitAction{
if (![self.songTextField.text isExist]) {
showToast(@"请输入歌曲名称");
return;
}
if (self.songModel == nil) {
if (self.giftModel == nil) {
showToast(@"请选择礼物");
return;
}
}
if (self.songModel) {
self.songModel.song_name = self.songTextField.text;
if (self.delegate && [self.delegate respondsToSelector:@selector(qx_mineEditSongViewCommitWithSongModel:)]) {
[self.delegate qx_mineEditSongViewCommitWithSongModel:self.songModel];
}
return;
}
if (self.delegate && [self.delegate respondsToSelector:@selector(qx_mineAddSongViewCommitWithSongName:giftModel:)]) {
[self.delegate qx_mineAddSongViewCommitWithSongName:self.songTextField.text giftModel:self.giftModel];
}
}
-(void)textFieldDidBeginEditing:(UITextField *)textField{
[UIView animateWithDuration:0.3 animations:^{
self.bgView.top = 100;
}];
}
-(void)textFieldDidEndEditing:(UITextField *)textField{
[UIView animateWithDuration:0.3 animations:^{
self.bgView.y = (SCREEN_HEIGHT-300)/2.0;
}];
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[self endEditing:YES];
}
-(void)showInView:(UIView *)view{
self.bgView.y = -SCREEN_HEIGHT;
[view addSubview:self];
[UIView animateWithDuration:0.3 delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:1.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.bgView.y = (SCREEN_HEIGHT-300)/2.0;
} completion:^(BOOL finished) {
}];
}
-(void)hide{
[UIView animateWithDuration:0.3 delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:1.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.bgView.y = SCREEN_HEIGHT;
} completion:^(BOOL finished) {
[self removeFromSuperview];
if (self.delegate && [self.delegate respondsToSelector:@selector(qx_mineAddSongViewDidRemove)]) {
[self.delegate qx_mineAddSongViewDidRemove];
}
}];
}
@end

View File

@@ -0,0 +1,21 @@
//
// QXMineSongListCell.h
// QXLive
//
// Created by 启星 on 2025/11/13.
//
#import <UIKit/UIKit.h>
#import "QXUserSongListModel.h"
NS_ASSUME_NONNULL_BEGIN
@interface QXMineSongListCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UILabel *songNameLabel;
@property (weak, nonatomic) IBOutlet UILabel *giftInfoLabel;
@property (weak, nonatomic) IBOutlet UILabel *giftPriceLabel;
@property (nonatomic,strong)QXUserSongListModel *model;
@property (weak, nonatomic) IBOutlet UIImageView *giftImageView;
+(instancetype)cellWithTableView:(UITableView *)tableView;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,39 @@
//
// QXMineSongListCell.m
// QXLive
//
// Created by on 2025/11/13.
//
#import "QXMineSongListCell.h"
@implementation QXMineSongListCell
+(instancetype)cellWithTableView:(UITableView *)tableView{
static NSString *cellId = @"QXMineSongListCell";
QXMineSongListCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (!cell) {
cell = [[NSBundle mainBundle] loadNibNamed:cellId owner:nil options:nil].lastObject;
cell.backgroundColor = [UIColor clearColor];
}
return cell;
}
-(void)setModel:(QXUserSongListModel *)model{
_model = model;
[self.giftImageView sd_setImageWithURL:[NSURL URLWithString:model.base_image]];
self.giftInfoLabel.text = [NSString stringWithFormat:@"x%@%@",model.gift_num,model.gift_name];
self.songNameLabel.text = model.song_name;
self.giftPriceLabel.text = model.gift_price;
}
- (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,85 @@
<?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" colorMatched="YES">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
<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="default" indentationWidth="10" rowHeight="148" id="KGk-i7-Jjw" customClass="QXMineSongListCell">
<rect key="frame" x="0.0" y="0.0" width="520" height="148"/>
<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="520" height="148"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="我的好兄弟我的好兄弟" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="R6F-cb-iI4">
<rect key="frame" x="16" y="65.666666666666671" width="160.66666666666666" height="17"/>
<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="x99娃哈哈..." textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="IFK-v2-Dnh">
<rect key="frame" x="186.66666666666666" y="63.666666666666657" width="104.99999999999997" height="21"/>
<constraints>
<constraint firstAttribute="width" constant="105" id="UjZ-hh-fPh"/>
<constraint firstAttribute="height" constant="21" id="t4e-T1-m1W"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="6JB-lz-KaY">
<rect key="frame" x="291.66666666666669" y="59" width="30" height="30"/>
<constraints>
<constraint firstAttribute="height" constant="30" id="rwb-vi-voD"/>
<constraint firstAttribute="width" constant="30" id="zrk-tg-EU9"/>
</constraints>
</imageView>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="mine_recharge_corn" translatesAutoresizingMaskIntoConstraints="NO" id="iTX-xW-714">
<rect key="frame" x="417.33333333333331" y="63.666666666666657" width="21" height="21"/>
<constraints>
<constraint firstAttribute="width" constant="21" id="krJ-ep-kn0"/>
<constraint firstAttribute="height" constant="21" id="qs1-ei-fkV"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="666666" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="oKh-AE-ANj">
<rect key="frame" x="441.33333333333331" y="63.666666666666657" width="62.666666666666686" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="1" green="0.15294117647058825" blue="0.15294117647058825" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstItem="iTX-xW-714" firstAttribute="centerY" secondItem="oKh-AE-ANj" secondAttribute="centerY" id="9TG-n1-UcK"/>
<constraint firstItem="6JB-lz-KaY" firstAttribute="centerY" secondItem="IFK-v2-Dnh" secondAttribute="centerY" id="MLe-5e-Fof"/>
<constraint firstAttribute="trailing" secondItem="oKh-AE-ANj" secondAttribute="trailing" constant="16" id="OHf-UM-rXC"/>
<constraint firstItem="IFK-v2-Dnh" firstAttribute="centerX" secondItem="H2p-sc-9uM" secondAttribute="centerX" constant="-21" id="Ub6-aa-FQz"/>
<constraint firstItem="oKh-AE-ANj" firstAttribute="leading" secondItem="iTX-xW-714" secondAttribute="trailing" constant="3" id="Ydx-YG-CJr"/>
<constraint firstItem="R6F-cb-iI4" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="16" id="Ym8-m2-L1D"/>
<constraint firstItem="IFK-v2-Dnh" firstAttribute="leading" secondItem="R6F-cb-iI4" secondAttribute="trailing" constant="10" id="aUV-fE-cou"/>
<constraint firstItem="6JB-lz-KaY" firstAttribute="leading" secondItem="IFK-v2-Dnh" secondAttribute="trailing" id="cvk-KI-IdC"/>
<constraint firstItem="R6F-cb-iI4" firstAttribute="centerY" secondItem="H2p-sc-9uM" secondAttribute="centerY" id="gqb-dZ-g4a"/>
<constraint firstItem="oKh-AE-ANj" firstAttribute="centerY" secondItem="H2p-sc-9uM" secondAttribute="centerY" id="za5-OT-ud2"/>
</constraints>
</tableViewCellContentView>
<constraints>
<constraint firstItem="IFK-v2-Dnh" firstAttribute="centerY" secondItem="KGk-i7-Jjw" secondAttribute="centerY" id="0Nk-VO-dFA"/>
</constraints>
<inset key="separatorInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
<connections>
<outlet property="giftImageView" destination="6JB-lz-KaY" id="wxn-7D-j03"/>
<outlet property="giftInfoLabel" destination="IFK-v2-Dnh" id="bUf-dC-HFC"/>
<outlet property="giftPriceLabel" destination="oKh-AE-ANj" id="obD-5U-Y99"/>
<outlet property="songNameLabel" destination="R6F-cb-iI4" id="VWf-YO-8zP"/>
</connections>
<point key="canvasLocation" x="291.60305343511448" y="56.338028169014088"/>
</tableViewCell>
</objects>
<resources>
<image name="mine_recharge_corn" width="20" height="20"/>
</resources>
</document>

View File

@@ -0,0 +1,74 @@
//
// QXAudioRecorderView.h
// QXLive
//
// Created by 启星 on 2025/11/13.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger, AudioRecorderState) {
AudioRecorderStateReady, // 准备状态
AudioRecorderStateRecording, // 录制中
AudioRecorderStateStopped, // 已停止
AudioRecorderStatePlaying // 试听中
};
@class QXAudioRecorderView;
@protocol QXAudioRecorderViewDelegate <NSObject>
@optional
/// 录音状态改变
- (void)qxAudioRecorderView:(QXAudioRecorderView *)recorderView didChangeState:(AudioRecorderState)state;
/// 录音完成
- (void)qxAudioRecorderView:(QXAudioRecorderView *)recorderView didFinishRecordingWithMP3File:(NSURL *)mp3FileURL duration:(NSTimeInterval)duration;
/// 录音失败
- (void)qxAudioRecorderView:(QXAudioRecorderView *)recorderView didFailWithError:(NSError *)error;
/// 录音进度更新
- (void)qxAudioRecorderView:(QXAudioRecorderView *)recorderView didUpdateProgress:(NSTimeInterval)progress totalDuration:(NSTimeInterval)totalDuration;
@end
@interface QXAudioRecorderView : UIView
@property (nonatomic, weak) id<QXAudioRecorderViewDelegate> delegate;
@property (nonatomic, assign, readonly) AudioRecorderState state;
@property (nonatomic, assign, readonly) NSTimeInterval currentDuration;
@property (nonatomic, assign, readonly) NSTimeInterval totalDuration; // 总录制时长(连续录制)
@property (nonatomic, strong, readonly) NSURL *currentAudioFileURL;
/// 最大录制时长默认300秒5分钟
@property (nonatomic, assign) NSTimeInterval maxDuration;
/// 是否显示试听按钮默认YES
@property (nonatomic, assign) BOOL showPlaybackButton;
/// 初始化
- (instancetype)initWithFrame:(CGRect)frame maxDuration:(NSTimeInterval)maxDuration;
/// 开始录制(程序控制)
- (void)startRecording;
/// 停止录制(程序控制)
- (void)stopRecording;
/// 试听录音
- (void)playRecording;
/// 停止试听
- (void)stopPlayback;
/// 重置录音从0开始
- (void)resetRecording;
/// 获取当前录制状态信息
- (NSString *)getRecordingStatus;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,755 @@
//
// QXAudioRecorderView.m
// QXLive
//
// Created by on 2025/11/13.
//
#import "QXAudioRecorderView.h"
#import <AVFoundation/AVFoundation.h>
#import "UIButton+QX.h"
#import "QXCOSUploadManager.h"
#import "QXMineNetwork.h"
@interface QXAudioRecorderView() <AVAudioRecorderDelegate, AVAudioPlayerDelegate,UIGestureRecognizerDelegate>
// UI Components
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UIView *recordContentView;
@property (nonatomic, strong) UIImageView *recordButton;
@property (nonatomic, strong) CAShapeLayer *progressLayer;
@property (nonatomic, strong) UILabel *timeLabel;
@property (nonatomic, strong) UILabel *stateLabel;
@property (nonatomic, strong) UIButton *playButton;
@property (nonatomic, strong) UIButton *resetButton;
@property (nonatomic, strong) UIButton *authBtn;
// Audio Components
@property (nonatomic, strong) AVAudioRecorder *audioRecorder;
@property (nonatomic, strong) AVAudioPlayer *audioPlayer;
@property (nonatomic, strong) NSURL *originalAudioFileURL;
@property (nonatomic, strong) NSURL *mp3AudioFileURL;
@property (nonatomic, strong) NSURL *tempAudioFileURL; //
// Recording State
@property (nonatomic, assign) AudioRecorderState state;
@property (nonatomic, assign) NSTimeInterval currentDuration; //
@property (nonatomic, assign) NSTimeInterval totalDuration; //
@property (nonatomic, assign) NSInteger recordingSessionCount; //
@property (nonatomic, strong) NSTimer *recordingTimer;
@property (nonatomic, assign) BOOL isCancelled;
@property (nonatomic, strong) NSMutableArray<NSURL *> *recordedSegments; //
@end
@implementation QXAudioRecorderView
- (instancetype)initWithFrame:(CGRect)frame {
return [self initWithFrame:frame maxDuration:300.0];
}
- (instancetype)initWithFrame:(CGRect)frame maxDuration:(NSTimeInterval)maxDuration {
self = [super initWithFrame:frame];
if (self) {
_maxDuration = maxDuration;
_showPlaybackButton = YES;
_state = AudioRecorderStateReady;
_recordedSegments = [NSMutableArray array];
_recordingSessionCount = 0;
[self setupUI];
[self setupAudioSession];
[self setupGestureRecognizers];
}
return self;
}
- (void)setupUI {
self.backgroundColor = [UIColor whiteColor];
[self addRoundedCornersWithRadius:16 byRoundingCorners:(UIRectCornerTopLeft|UIRectCornerTopRight)];
self.authBtn = [[UIButton alloc] initWithFrame:CGRectMake(SCREEN_WIDTH-ScaleWidth(57)-16, 16, ScaleWidth(57), ScaleWidth(20))];
[self.authBtn setImage:[UIImage imageNamed:@"singer_auth_btn"] forState:(UIControlStateNormal)];
[self.authBtn addTarget:self action:@selector(authAction) forControlEvents:(UIControlEventTouchUpInside)];
[self addSubview:self.authBtn];
self.titleLabel = [[UILabel alloc] initWithFrame:CGRectMake((SCREEN_WIDTH-150)/2, 18, 150, 24)];
self.titleLabel.textColor = RGB16(0x333333);
self.titleLabel.font = [UIFont boldSystemFontOfSize:16];
self.titleLabel.text = @"我的认证";
self.titleLabel.textAlignment = NSTextAlignmentCenter;
[self addSubview:self.titleLabel];
self.recordContentView = [[UIView alloc] init];
[self addSubview:self.recordContentView];
//
self.recordButton = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"singer_record_btn"]];
self.recordButton.userInteractionEnabled = YES;
[self.recordContentView addSubview:self.recordButton];
//
self.progressLayer = [CAShapeLayer layer];
self.progressLayer.fillColor = [UIColor clearColor].CGColor;
self.progressLayer.strokeColor = QXConfig.themeColor.CGColor;
self.progressLayer.lineWidth = 4;
self.progressLayer.strokeEnd = 0;
//
self.progressLayer.strokeStart = 0; //
self.progressLayer.strokeEnd = 0; // 0
// transform
self.progressLayer.transform = CATransform3DIdentity;
self.progressLayer.lineCap = kCALineCapRound;
[self.recordContentView.layer addSublayer:self.progressLayer];
//
self.timeLabel = [[UILabel alloc] init];
self.timeLabel.text = [self formattedTime:0];
self.timeLabel.textAlignment = NSTextAlignmentCenter;
self.timeLabel.font = [UIFont systemFontOfSize:12];
self.timeLabel.textColor = RGB16A(0x000000, 0.45);
[self addSubview:self.timeLabel];
//
self.stateLabel = [[UILabel alloc] init];
self.stateLabel.text = @"长按录音";
self.stateLabel.textAlignment = NSTextAlignmentCenter;
self.stateLabel.font = [UIFont systemFontOfSize:14];
self.stateLabel.textColor = [UIColor grayColor];
[self addSubview:self.stateLabel];
//
// //
// self.sessionLabel = [[UILabel alloc] init];
// self.sessionLabel.text = @"";
// self.sessionLabel.textAlignment = NSTextAlignmentCenter;
// self.sessionLabel.font = [UIFont systemFontOfSize:12];
// self.sessionLabel.textColor = [UIColor lightGrayColor];
// [self addSubview:self.sessionLabel];
//
self.playButton = [[UIButton alloc] init];
[self.playButton setTitle:@"试听" forState:UIControlStateNormal];
[self.playButton setTitleColor:RGB16A(0x000000, 0.45) forState:(UIControlStateNormal)];
self.playButton.titleLabel.font = [UIFont systemFontOfSize:12];
[self.playButton setImage:[UIImage imageNamed:@"singer_try_listen"] forState:(UIControlStateNormal)];
[self.playButton addTarget:self action:@selector(playButtonTapped) forControlEvents:UIControlEventTouchUpInside];
// self.playButton.hidden = YES;
[self addSubview:self.playButton];
//
self.resetButton = [[UIButton alloc] init];
[self.resetButton setTitle:@"重置" forState:UIControlStateNormal];
[self.resetButton setImage:[UIImage imageNamed:@"singer_reset_record"] forState:(UIControlStateNormal)];
[self.resetButton setTitleColor:RGB16A(0x000000, 0.45) forState:(UIControlStateNormal)];
self.resetButton.titleLabel.font = [UIFont systemFontOfSize:12];
[self.resetButton addTarget:self action:@selector(resetButtonTapped) forControlEvents:UIControlEventTouchUpInside];
// self.resetButton.hidden = YES;
[self addSubview:self.resetButton];
[self.recordContentView bringSubviewToFront:self.recordButton];
}
- (void)setupAudioSession {
// AVAudioSession *audioSession = [AVAudioSession sharedInstance];
// NSError *error = nil;
// [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
// [audioSession setActive:YES error:&error];
//
// if (error) {
// NSLog(@"Audio session setup error: %@", error);
// }
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *error = nil;
// 使 Playback 使
[audioSession setCategory:AVAudioSessionCategoryPlayback error:&error];
// 使 PlayAndRecord
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord
withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker
error:&error];
[audioSession setActive:YES error:&error];
if (error) {
NSLog(@"Audio session setup error: %@", error);
}
}
- (void)setupGestureRecognizers {
// -
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
longPress.minimumPressDuration = 0.3;
longPress.delegate = self;
[self.recordButton addGestureRecognizer:longPress];
}
-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
return YES;
}
- (void)layoutSubviews {
[super layoutSubviews];
CGFloat centerX = CGRectGetWidth(self.bounds) / 2;
//
self.timeLabel.frame = CGRectMake((SCREEN_WIDTH-150)/2, self.titleLabel.bottom+4, 150, 30);
//
self.recordContentView.frame = CGRectMake(centerX - 50.5, self.timeLabel.bottom+22, 101, 101);
self.recordButton.frame = CGRectMake(11, 11, 80, 80);
//
CGRect progressRect = CGRectInset(self.recordContentView.bounds, 4, 4);
UIBezierPath *progressPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(CGRectGetMidX(progressRect), CGRectGetMidY(progressRect))
radius:progressRect.size.width / 2
startAngle:-M_PI_2 // -90
endAngle:-M_PI_2 + M_PI * 2 //
clockwise:YES];
self.progressLayer.path = progressPath.CGPath;
// //
self.stateLabel.frame = CGRectMake(0, self.recordContentView.bottom, CGRectGetWidth(self.bounds), 20);
//
// //
// self.sessionLabel.frame = CGRectMake(0, 205, CGRectGetWidth(self.bounds), 20);
//
self.playButton.frame = CGRectMake(SCREEN_WIDTH-38-35, self.recordContentView.top+35, 38, 60);
self.resetButton.frame = CGRectMake(35, self.recordContentView.top+35, 38, 60);
[self.playButton qx_layoutButtonNOSizeToFitWithEdgeInsetsStyle:(QXButtonEdgeInsetsStyleTop) imageTitleSpace:2];
[self.resetButton qx_layoutButtonNOSizeToFitWithEdgeInsetsStyle:(QXButtonEdgeInsetsStyleTop) imageTitleSpace:2];
}
-(void)authAction{
///
///
if ((int)self.totalDuration < 5) {
showToast(@"录音时长不得小于60秒");
return;
}
if (self.originalAudioFileURL==nil) {
showToast(@"录制文件不存在");
return;
}
NSData *data = [NSData dataWithContentsOfURL:self.originalAudioFileURL];
@weakify(self)
showLoadingInView(self.viewController.view);
[[QXCOSUploadManager shareManager] audioUploadFile:data withObjectKey:self.originalAudioFileURL.lastPathComponent complete:^(NSString * _Nonnull fileUrl, QXCOSUploadImageState state) {
@strongify(self);
dispatch_async(dispatch_get_main_queue(), ^{
hideLoadingInView(self.viewController.view);
if ([fileUrl isExist]) {
[QXMineNetwork singerAuthWithSong:fileUrl successBlock:^(NSDictionary * _Nonnull dict) {
showToast(@"上传成功");
} failBlock:^(NSError * _Nonnull error, NSString * _Nonnull msg) {
showToast(@"上传失败");
}];
}else{
showToast(@"上传失败");
}
});
}];
}
#pragma mark - Gesture Handlers
- (void)handleLongPress:(UILongPressGestureRecognizer *)gesture {
CGPoint touchPoint = [gesture locationInView:self];
switch (gesture.state) {
case UIGestureRecognizerStateBegan:
[self stopPlayback];
NSLog(@"开始录制 - 第%ld段", (long)self.recordingSessionCount + 1);
self.isCancelled = NO;
[self startRecording];
break;
case UIGestureRecognizerStateChanged:
//
if (touchPoint.y < CGRectGetMinY(self.recordButton.frame) - 20) {
if (!self.isCancelled) {
NSLog(@"取消录制");
self.isCancelled = YES;
[self updateUIForCancelled];
}
} else {
if (self.isCancelled) {
NSLog(@"恢复录制");
self.isCancelled = NO;
[self updateUIForRecording];
}
}
break;
case UIGestureRecognizerStateEnded:
case UIGestureRecognizerStateCancelled:
NSLog(@"结束录制 - 当前段时长: %.1f秒", self.currentDuration);
if (self.isCancelled) {
[self cancelRecording];
} else {
[self stopRecording];
}
break;
default:
break;
}
}
#pragma mark - Recording Control
- (void)startRecording {
if (self.state == AudioRecorderStateRecording) return;
//
NSURL *audioFileURL = [self generateAudioFileURL];
NSDictionary *recordSettings = @{
AVFormatIDKey: @(kAudioFormatLinearPCM),
AVSampleRateKey: @44100.0,
AVNumberOfChannelsKey: @1,
AVEncoderAudioQualityKey: @(AVAudioQualityHigh)
};
NSError *error = nil;
self.audioRecorder = [[AVAudioRecorder alloc] initWithURL:audioFileURL settings:recordSettings error:&error];
self.audioRecorder.delegate = self;
self.audioRecorder.meteringEnabled = YES;
if (error) {
NSLog(@"录音器初始化失败: %@", error);
if ([self.delegate respondsToSelector:@selector(qxAudioRecorderView:didFailWithError:)]) {
[self.delegate qxAudioRecorderView:self didFailWithError:error];
}
return;
}
if ([self.audioRecorder record]) {
self.state = AudioRecorderStateRecording;
self.recordingSessionCount++;
[self startRecordingTimer];
[self updateUIForRecording];
if ([self.delegate respondsToSelector:@selector(qxAudioRecorderView:didChangeState:)]) {
[self.delegate qxAudioRecorderView:self didChangeState:self.state];
}
}
}
- (void)stopRecording {
if (self.state != AudioRecorderStateRecording) return;
[self.recordingTimer invalidate];
self.recordingTimer = nil;
NSTimeInterval segmentDuration = self.currentDuration;
[self.audioRecorder stop];
//
if (segmentDuration > 0.5) { // 0.5
[self.recordedSegments addObject:self.audioRecorder.url];
self.totalDuration += segmentDuration;
NSLog(@"保存音频段,时长: %.1f秒,总时长: %.1f秒", segmentDuration, self.totalDuration);
}
self.audioRecorder = nil;
self.currentDuration = 0;
self.state = AudioRecorderStateStopped;
[self updateUIForStopped];
//
if (self.recordedSegments.count > 0) {
[self mergeAudioSegments];
}
if ([self.delegate respondsToSelector:@selector(qxAudioRecorderView:didChangeState:)]) {
[self.delegate qxAudioRecorderView:self didChangeState:self.state];
}
}
- (void)cancelRecording {
if (self.state != AudioRecorderStateRecording) return;
[self.recordingTimer invalidate];
self.recordingTimer = nil;
[self.audioRecorder stop];
[self.audioRecorder deleteRecording];
self.audioRecorder = nil;
self.currentDuration = 0;
self.state = AudioRecorderStateStopped;
[self updateUIForStopped];
if ([self.delegate respondsToSelector:@selector(qxAudioRecorderView:didChangeState:)]) {
[self.delegate qxAudioRecorderView:self didChangeState:self.state];
}
}
#pragma mark - Audio Merging
- (void)mergeAudioSegments {
if (self.recordedSegments.count == 0) return;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//
NSURL *mergedFileURL = [self generateAudioFileURLWithExtension:@"m4a"];
//
AVMutableComposition *composition = [AVMutableComposition composition];
CMTime currentTime = kCMTimeZero;
for (NSURL *audioURL in self.recordedSegments) {
AVURLAsset *audioAsset = [AVURLAsset assetWithURL:audioURL];
CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, audioAsset.duration);
//
AVMutableCompositionTrack *audioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
AVAssetTrack *sourceAudioTrack = [[audioAsset tracksWithMediaType:AVMediaTypeAudio] firstObject];
if (sourceAudioTrack) {
[audioTrack insertTimeRange:timeRange ofTrack:sourceAudioTrack atTime:currentTime error:nil];
currentTime = CMTimeAdd(currentTime, audioAsset.duration);
}
}
//
AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:composition presetName:AVAssetExportPresetAppleM4A];
exportSession.outputURL = mergedFileURL;
exportSession.outputFileType = AVFileTypeAppleM4A;
[exportSession exportAsynchronouslyWithCompletionHandler:^{
dispatch_async(dispatch_get_main_queue(), ^{
if (exportSession.status == AVAssetExportSessionStatusCompleted) {
self.originalAudioFileURL = mergedFileURL;
NSLog(@"音频合并完成,总时长: %.1f秒", self.totalDuration);
// MP3
[self convertToMP3];
} else {
NSLog(@"音频合并失败: %@", exportSession.error);
}
});
}];
});
}
#pragma mark - Reset Function
- (void)resetRecording {
NSLog(@"重置录音");
[self stopPlayback];
[self cancelRecording];
//
for (NSURL *segmentURL in self.recordedSegments) {
[[NSFileManager defaultManager] removeItemAtURL:segmentURL error:nil];
}
[self.recordedSegments removeAllObjects];
//
if (self.originalAudioFileURL) {
[[NSFileManager defaultManager] removeItemAtURL:self.originalAudioFileURL error:nil];
self.originalAudioFileURL = nil;
}
if (self.mp3AudioFileURL) {
[[NSFileManager defaultManager] removeItemAtURL:self.mp3AudioFileURL error:nil];
self.mp3AudioFileURL = nil;
}
//
self.totalDuration = 0;
self.currentDuration = 0;
self.recordingSessionCount = 0;
self.state = AudioRecorderStateReady;
[self updateUIForReady];
if ([self.delegate respondsToSelector:@selector(qxAudioRecorderView:didChangeState:)]) {
[self.delegate qxAudioRecorderView:self didChangeState:self.state];
}
}
#pragma mark - Playback Control
- (void)playButtonTapped {
if (self.state == AudioRecorderStatePlaying) {
[self stopPlayback];
} else {
[self playRecording];
}
}
- (void)playRecording {
if (self.state == AudioRecorderStatePlaying) return;
NSURL *playbackURL = self.mp3AudioFileURL ?: self.originalAudioFileURL;
if (!playbackURL){
showToast(@"您还未录制声音");
return;
}
//
// AVAudioSession *audioSession = [AVAudioSession sharedInstance];
// NSError *error = nil;
// [audioSession setCategory:AVAudioSessionCategoryPlayback error:&error];
// [audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&error];
// [audioSession setActive:YES error:&error];
NSError *playerError = nil;
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:playbackURL error:&playerError];
self.audioPlayer.delegate = self;
if (playerError) {
NSLog(@"播放器初始化失败: %@", playerError);
return;
}
if ([self.audioPlayer play]) {
self.state = AudioRecorderStatePlaying;
[self updateUIForPlaying];
if ([self.delegate respondsToSelector:@selector(qxAudioRecorderView:didChangeState:)]) {
[self.delegate qxAudioRecorderView:self didChangeState:self.state];
}
}
}
- (void)stopPlayback {
if (self.state != AudioRecorderStatePlaying) return;
[self.audioPlayer stop];
self.audioPlayer = nil;
self.state = AudioRecorderStateStopped;
[self updateUIForStopped];
if ([self.delegate respondsToSelector:@selector(qxAudioRecorderView:didChangeState:)]) {
[self.delegate qxAudioRecorderView:self didChangeState:self.state];
}
}
- (void)resetButtonTapped {
[self resetRecording];
}
#pragma mark - Timer
- (void)startRecordingTimer {
self.currentDuration = 0;
self.recordingTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(updateRecordingProgress) userInfo:nil repeats:YES];
}
- (void)updateRecordingProgress {
if (self.state != AudioRecorderStateRecording) return;
self.currentDuration += 0.1;
// UI
[self updateProgress];
[self updateTimeLabel];
//
if ([self.delegate respondsToSelector:@selector(qxAudioRecorderView:didUpdateProgress:totalDuration:)]) {
[self.delegate qxAudioRecorderView:self didUpdateProgress:self.currentDuration totalDuration:self.totalDuration + self.currentDuration];
}
//
if ((self.totalDuration + self.currentDuration) >= self.maxDuration) {
[self stopRecording];
}
}
#pragma mark - UI Updates
- (void)updateUIForReady {
self.progressLayer.strokeEnd = 0;
self.timeLabel.text = [self formattedTime:0];
self.stateLabel.text = @"长按录音";
//
// self.playButton.hidden = YES;
// self.resetButton.hidden = YES;
}
- (void)updateUIForRecording {
self.stateLabel.text = self.isCancelled ? @"松开手指取消" : @"录音中...松开结束";
// self.playButton.hidden = YES;
// self.resetButton.hidden = YES;
}
- (void)updateUIForStopped {
self.stateLabel.text = @"继续录音";
if (self.totalDuration > 0) {
if (self.showPlaybackButton) {
// self.playButton.hidden = NO;
// self.resetButton.hidden = NO;
[self.playButton setTitle:@"试听" forState:UIControlStateNormal];
[self.playButton setImage:[UIImage imageNamed:@"singer_try_listen"] forState:UIControlStateNormal];
}
} else {
// self.playButton.hidden = YES;
// self.resetButton.hidden = YES;
}
// self.stateLabel.textColor = [UIColor grayColor];
}
- (void)updateUIForPlaying {
// self.stateLabel.text = @"试听中...";
// self.stateLabel.textColor = [UIColor blueColor];
[self.playButton setTitle:@"停止" forState:UIControlStateNormal];
[self.playButton setImage:[UIImage imageNamed:@"singer_listen_stop"] forState:UIControlStateNormal];
}
- (void)updateUIForCancelled {
// self.stateLabel.text = @"松开手指取消";
// self.stateLabel.textColor = [UIColor redColor];
}
- (void)updateProgress {
CGFloat totalProgress = (self.totalDuration + self.currentDuration) / self.maxDuration;
self.progressLayer.strokeEnd = totalProgress;
// //
// if (totalProgress > 0.8) {
// self.progressLayer.strokeColor = [UIColor redColor].CGColor;
// } else if (totalProgress > 0.6) {
// self.progressLayer.strokeColor = [UIColor orangeColor].CGColor;
// } else {
// self.progressLayer.strokeColor = [UIColor colorWithRed:0.0 green:0.48 blue:1.0 alpha:1.0].CGColor;
// }
}
- (void)updateTimeLabel {
NSTimeInterval currentTotal = self.totalDuration + self.currentDuration;
self.timeLabel.text = [self formattedTime:currentTotal];
}
#pragma mark - MP3 Conversion
- (void)convertToMP3 {
// if (!self.originalAudioFileURL) return;
//
// dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// NSString *mp3FileName = [NSString stringWithFormat:@"%@.mp3", [[NSUUID UUID] UUIDString]];
// NSString *mp3FilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:mp3FileName];
// self.mp3AudioFileURL = [NSURL fileURLWithPath:mp3FilePath];
//
// @try {
// int read, write;
//
// FILE *pcm = fopen([[self.originalAudioFileURL path] UTF8String], "rb");
// FILE *mp3 = fopen([mp3FilePath UTF8String], "wb");
//
// const int PCM_SIZE = 8192;
// const int MP3_SIZE = 8192;
// short int pcm_buffer[PCM_SIZE * 2];
// unsigned char mp3_buffer[MP3_SIZE];
//
// lame_t lame = lame_init();
// lame_set_in_samplerate(lame, 44100);
// lame_set_VBR(lame, vbr_default);
// lame_init_params(lame);
//
// do {
// read = (int)fread(pcm_buffer, 2 * sizeof(short int), PCM_SIZE, pcm);
// if (read == 0)
// write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
// else
// write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
//
// fwrite(mp3_buffer, write, 1, mp3);
//
// } while (read != 0);
//
// lame_close(lame);
// fclose(mp3);
// fclose(pcm);
// }
// @catch (NSException *exception) {
// NSLog(@"MP3转换失败: %@", exception);
// self.mp3AudioFileURL = nil;
// }
// @finally {
// dispatch_async(dispatch_get_main_queue(), ^{
// if (self.mp3AudioFileURL && [self.delegate respondsToSelector:@selector(audioRecorderView:didFinishRecordingWithMP3File:duration:)]) {
// [self.delegate audioRecorderView:self didFinishRecordingWithMP3File:self.mp3AudioFileURL duration:self.totalDuration];
// }
// });
// }
// });
}
#pragma mark - Utility Methods
- (NSURL *)generateAudioFileURL {
return [self generateAudioFileURLWithExtension:@"caf"];
}
- (NSURL *)generateAudioFileURLWithExtension:(NSString *)extension {
long long time = [[NSDate date] timeIntervalSince1970];
NSString *fileName = [NSString stringWithFormat:@"%lld.%@", time ,extension];
NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:fileName];
return [NSURL fileURLWithPath:filePath];
}
- (NSString *)formattedTime:(NSTimeInterval)time {
int minutes = (int)time / 60;
int seconds = (int)time % 60;
int maxMinutes = (int)_maxDuration / 60;
int maxSeconds = (int)_maxDuration % 60;
return [NSString stringWithFormat:@"%02d:%02d | %02d:%02d", minutes, seconds,maxMinutes,maxSeconds];
}
- (NSString *)getRecordingStatus {
if (self.totalDuration > 0) {
return [NSString stringWithFormat:@"已录制%.1f秒,共%ld段", self.totalDuration, (long)self.recordingSessionCount];
} else {
return @"未开始录制";
}
}
#pragma mark - AVAudioRecorderDelegate
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag {
NSLog(@"录音完成: %@", flag ? @"成功" : @"失败");
}
- (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *)error {
NSLog(@"录音编码错误: %@", error);
if ([self.delegate respondsToSelector:@selector(qxAudioRecorderView:didFailWithError:)]) {
[self.delegate qxAudioRecorderView:self didFailWithError:error];
}
}
#pragma mark - AVAudioPlayerDelegate
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
[self stopPlayback];
}
- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error {
NSLog(@"播放解码错误: %@", error);
[self stopPlayback];
}
#pragma mark - Public Properties
- (NSURL *)currentAudioFileURL {
return self.mp3AudioFileURL ?: self.originalAudioFileURL;
}
- (void)dealloc {
[self.recordingTimer invalidate];
[self.audioRecorder stop];
[self.audioPlayer stop];
}
@end

View File

@@ -101,7 +101,7 @@
[self.currenNobilityImageView mas_makeConstraints:^(MASConstraintMaker *make) { [self.currenNobilityImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.mas_equalTo(-28); make.right.mas_equalTo(-28);
make.height.width.mas_equalTo(ScaleWidth(104)); make.height.width.mas_equalTo(ScaleWidth(104));
make.bottom.mas_equalTo(-34); make.top.mas_equalTo(13);
}]; }];
self.compareImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"nobility_compare_top"]]; self.compareImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"nobility_compare_top"]];
@@ -118,6 +118,7 @@
_model = model; _model = model;
[self.userAvatarView setHeadIcon:model.user_info.avatar dress:@""]; [self.userAvatarView setHeadIcon:model.user_info.avatar dress:@""];
self.userNameLabel.text = [NSString stringWithFormat:@"%@的爵位",model.user_info.nickname]; self.userNameLabel.text = [NSString stringWithFormat:@"%@的爵位",model.user_info.nickname];
[self.currenNobilityImageView sd_setImageWithURL:[NSURL URLWithString:model.nobility_info.image]];
if (model.nobility_info.status.intValue == 0) { if (model.nobility_info.status.intValue == 0) {
[self setHaveNobility:NO]; [self setHaveNobility:NO];
}else{ }else{

View File

@@ -11,36 +11,36 @@
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/> <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" rowHeight="85" id="KGk-i7-Jjw" customClass="QXCornRecordCell"> <tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" rowHeight="85" id="KGk-i7-Jjw" customClass="QXCornRecordCell">
<rect key="frame" x="0.0" y="0.0" width="393" height="85"/> <rect key="frame" x="0.0" y="0.0" width="393" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <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"> <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="393" height="85"/> <rect key="frame" x="0.0" y="0.0" width="393" height="66"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="每日签到" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9Ov-rS-XTy"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="每日签到" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9Ov-rS-XTy">
<rect key="frame" x="16" y="12" width="242" height="21"/> <rect key="frame" x="16" y="12" width="242" height="17"/>
<constraints>
<constraint firstAttribute="height" constant="21" id="M6b-EW-qW0"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/> <fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.84705882349999995" colorSpace="calibratedRGB"/> <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.84705882349999995" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="2024.12.14 11:22:55" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fEd-EE-hdG"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="2024.12.14 11:22:55" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fEd-EE-hdG">
<rect key="frame" x="16" y="56" width="357" height="15"/> <rect key="frame" x="16" y="37" width="357" height="15"/>
<constraints>
<constraint firstAttribute="height" constant="15" id="oeb-i6-pPH"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="12"/> <fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="mine_recharge_corn" translatesAutoresizingMaskIntoConstraints="NO" id="otM-9U-0Vb"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="mine_recharge_corn" translatesAutoresizingMaskIntoConstraints="NO" id="otM-9U-0Vb">
<rect key="frame" x="361" y="14.666666666666664" width="16" height="16"/> <rect key="frame" x="361" y="12.666666666666664" width="16" height="16"/>
<constraints> <constraints>
<constraint firstAttribute="width" constant="16" id="TBo-Q1-4cA"/> <constraint firstAttribute="width" constant="16" id="TBo-Q1-4cA"/>
<constraint firstAttribute="height" constant="16" id="XDZ-Mi-dJN"/> <constraint firstAttribute="height" constant="16" id="XDZ-Mi-dJN"/>
</constraints> </constraints>
</imageView> </imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="+99999" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Fxs-N2-aqw"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="+99999" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Fxs-N2-aqw">
<rect key="frame" x="278" y="12.666666666666664" width="80" height="20"/> <rect key="frame" x="278" y="10" width="80" height="21"/>
<constraints> <constraints>
<constraint firstAttribute="width" constant="80" id="wGg-jd-N7q"/> <constraint firstAttribute="width" constant="80" id="wGg-jd-N7q"/>
</constraints> </constraints>
@@ -55,9 +55,11 @@
<constraint firstItem="9Ov-rS-XTy" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="16" id="7Wh-Dd-Lsz"/> <constraint firstItem="9Ov-rS-XTy" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="16" id="7Wh-Dd-Lsz"/>
<constraint firstItem="otM-9U-0Vb" firstAttribute="leading" secondItem="Fxs-N2-aqw" secondAttribute="trailing" constant="3" id="JOW-D1-VCO"/> <constraint firstItem="otM-9U-0Vb" firstAttribute="leading" secondItem="Fxs-N2-aqw" secondAttribute="trailing" constant="3" id="JOW-D1-VCO"/>
<constraint firstAttribute="bottom" secondItem="fEd-EE-hdG" secondAttribute="bottom" constant="14" id="R8J-ww-6pD"/> <constraint firstAttribute="bottom" secondItem="fEd-EE-hdG" secondAttribute="bottom" constant="14" id="R8J-ww-6pD"/>
<constraint firstItem="fEd-EE-hdG" firstAttribute="top" secondItem="9Ov-rS-XTy" secondAttribute="bottom" constant="8" symbolic="YES" id="fCg-5y-4fZ"/>
<constraint firstAttribute="trailing" secondItem="fEd-EE-hdG" secondAttribute="trailing" constant="20" id="g4d-4v-ibb"/> <constraint firstAttribute="trailing" secondItem="fEd-EE-hdG" secondAttribute="trailing" constant="20" id="g4d-4v-ibb"/>
<constraint firstItem="Fxs-N2-aqw" firstAttribute="leading" secondItem="9Ov-rS-XTy" secondAttribute="trailing" constant="20" id="kVM-pQ-Cml"/> <constraint firstItem="Fxs-N2-aqw" firstAttribute="leading" secondItem="9Ov-rS-XTy" secondAttribute="trailing" constant="20" id="kVM-pQ-Cml"/>
<constraint firstItem="fEd-EE-hdG" firstAttribute="leading" secondItem="9Ov-rS-XTy" secondAttribute="leading" id="mlg-f5-ftM"/> <constraint firstItem="fEd-EE-hdG" firstAttribute="leading" secondItem="9Ov-rS-XTy" secondAttribute="leading" id="mlg-f5-ftM"/>
<constraint firstItem="fEd-EE-hdG" firstAttribute="top" secondItem="Fxs-N2-aqw" secondAttribute="bottom" constant="6" id="mty-CM-7Gg"/>
<constraint firstItem="Fxs-N2-aqw" firstAttribute="centerY" secondItem="9Ov-rS-XTy" secondAttribute="centerY" id="ubr-E6-gOU"/> <constraint firstItem="Fxs-N2-aqw" firstAttribute="centerY" secondItem="9Ov-rS-XTy" secondAttribute="centerY" id="ubr-E6-gOU"/>
<constraint firstItem="otM-9U-0Vb" firstAttribute="centerY" secondItem="9Ov-rS-XTy" secondAttribute="centerY" id="wqd-tc-4FI"/> <constraint firstItem="otM-9U-0Vb" firstAttribute="centerY" secondItem="9Ov-rS-XTy" secondAttribute="centerY" id="wqd-tc-4FI"/>
</constraints> </constraints>

View File

@@ -62,6 +62,7 @@
[[NSNotificationCenter defaultCenter] postNotificationName:noticeTencentLogin object:nil]; [[NSNotificationCenter defaultCenter] postNotificationName:noticeTencentLogin object:nil];
[TIMPushManager addPushListener:self]; [TIMPushManager addPushListener:self];
[[V2TIMManager sharedInstance] addConversationListener:self]; [[V2TIMManager sharedInstance] addConversationListener:self];
[[QXRoomMessageManager shared] addC2CObserver];
[self configAppPush]; [self configAppPush];
[self getHomeMessage]; [self getHomeMessage];
[V2TIMManager.sharedInstance addIMSDKListener:self]; [V2TIMManager.sharedInstance addIMSDKListener:self];

View File

@@ -261,6 +261,7 @@
if ([QXGlobal.shareGlobal.roomId isExist]) { if ([QXGlobal.shareGlobal.roomId isExist]) {
[[QXGiftPlayerManager shareManager] stopPlay]; [[QXGiftPlayerManager shareManager] stopPlay];
[[QXGiftDisplayManager sharedManager] inBackGround]; [[QXGiftDisplayManager sharedManager] inBackGround];
[[QXGlobal shareGlobal] dirfViewDidToBackground];
} }
} }
-(void)applicationWillResignActive:(UIApplication *)application{ -(void)applicationWillResignActive:(UIApplication *)application{
@@ -270,6 +271,7 @@
if ([QXGlobal.shareGlobal.roomId isExist]) { if ([QXGlobal.shareGlobal.roomId isExist]) {
[[QXGiftPlayerManager shareManager] startPlay]; [[QXGiftPlayerManager shareManager] startPlay];
[[QXGiftDisplayManager sharedManager] becomeFront]; [[QXGiftDisplayManager sharedManager] becomeFront];
[[QXGlobal shareGlobal] dirfViewBecomeToFront];
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

View File

@@ -5,12 +5,12 @@
"scale" : "1x" "scale" : "1x"
}, },
{ {
"filename" : "花瓣素材_金色的3D立体金币元素_101119090 1@2x.png", "filename" : "mine_live_gift_corn@2x.png",
"idiom" : "universal", "idiom" : "universal",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"filename" : "花瓣素材_金色的3D立体金币元素_101119090 1@3x.png", "filename" : "mine_live_gift_corn@3x.png",
"idiom" : "universal", "idiom" : "universal",
"scale" : "3x" "scale" : "3x"
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -5,11 +5,12 @@
"scale" : "1x" "scale" : "1x"
}, },
{ {
"filename" : "花瓣素材_金色的3D立体金币元素_101119090 1@2x.png", "filename" : "mine_recharge_corn@2x.png",
"idiom" : "universal", "idiom" : "universal",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"filename" : "mine_recharge_corn@3x.png",
"idiom" : "universal", "idiom" : "universal",
"scale" : "3x" "scale" : "3x"
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "service_singer_auth@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "service_singer_auth@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -5,12 +5,12 @@
"scale" : "1x" "scale" : "1x"
}, },
{ {
"filename" : "Customer Support@2x.png", "filename" : "service_songlist@2x.png",
"idiom" : "universal", "idiom" : "universal",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"filename" : "Customer Support@3x.png", "filename" : "service_songlist@3x.png",
"idiom" : "universal", "idiom" : "universal",
"scale" : "3x" "scale" : "3x"
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@@ -5,12 +5,11 @@
"scale" : "1x" "scale" : "1x"
}, },
{ {
"filename" : "Mask group@2x.png", "filename" : "singer_auth_bg@2x.png",
"idiom" : "universal", "idiom" : "universal",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"filename" : "Mask group@3x.png",
"idiom" : "universal", "idiom" : "universal",
"scale" : "3x" "scale" : "3x"
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 872 KiB

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "singer_auth_btn@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "singer_auth_btn@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "singer_auth_center_bg@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "singer_auth_center_bg@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "singer_auth_status_no@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "singer_auth_status_no@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Some files were not shown because too many files have changed in this diff Show More