增加换肤功能

This commit is contained in:
启星
2025-08-14 10:07:49 +08:00
parent f6964c1e89
commit 4f9318d98e
8789 changed files with 978530 additions and 2 deletions

View File

@@ -0,0 +1,18 @@
//
// QXUserInfoEditCell.h
// QXLive
//
// Created by 启星 on 2025/5/20.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface QXUserInfoEditCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
@property (weak, nonatomic) IBOutlet UITextField *textField;
+(instancetype)cellWithTableView:(UITableView *)tableView;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,31 @@
//
// QXUserInfoEditCell.m
// QXLive
//
// Created by on 2025/5/20.
//
#import "QXUserInfoEditCell.h"
@implementation QXUserInfoEditCell
+(instancetype)cellWithTableView:(UITableView *)tableView{
static NSString *cellId = @"QXUserInfoEditCell";
QXUserInfoEditCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (!cell) {
cell = [[NSBundle mainBundle] loadNibNamed:cellId owner:nil options:nil].lastObject;
cell.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,66 @@
<?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="default" indentationWidth="10" rowHeight="121" id="KGk-i7-Jjw" customClass="QXUserInfoEditCell">
<rect key="frame" x="0.0" y="0.0" width="446" height="121"/>
<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="446" height="121"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="TgL-rR-nuf">
<rect key="frame" x="16" y="52" width="70" height="17"/>
<constraints>
<constraint firstAttribute="width" constant="70" id="yA5-8Q-P0V"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<textField opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="248" contentHorizontalAlignment="left" contentVerticalAlignment="center" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="RL3-7c-bnu">
<rect key="frame" x="116" y="50" width="280" height="21"/>
<color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<textInputTraits key="textInputTraits"/>
</textField>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="arrowRight" translatesAutoresizingMaskIntoConstraints="NO" id="okn-C5-YbU">
<rect key="frame" x="406" y="48.666666666666664" width="24" height="23.999999999999993"/>
<constraints>
<constraint firstAttribute="width" constant="24" id="7Jo-BL-h1O"/>
<constraint firstAttribute="height" constant="24" id="AwW-eh-n6F"/>
</constraints>
</imageView>
</subviews>
<constraints>
<constraint firstItem="TgL-rR-nuf" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="16" id="1ND-Uq-ZxA"/>
<constraint firstItem="RL3-7c-bnu" firstAttribute="leading" secondItem="TgL-rR-nuf" secondAttribute="trailing" constant="30" id="U79-hX-qzV"/>
<constraint firstItem="okn-C5-YbU" firstAttribute="leading" secondItem="RL3-7c-bnu" secondAttribute="trailing" constant="10" id="cxM-JH-W4m"/>
<constraint firstAttribute="trailing" secondItem="okn-C5-YbU" secondAttribute="trailing" constant="16" id="kJo-zv-8QV"/>
</constraints>
</tableViewCellContentView>
<viewLayoutGuide key="safeArea" id="aW0-zy-SZf"/>
<constraints>
<constraint firstItem="TgL-rR-nuf" firstAttribute="centerY" secondItem="aW0-zy-SZf" secondAttribute="centerY" id="26h-i4-67a"/>
<constraint firstItem="RL3-7c-bnu" firstAttribute="centerY" secondItem="aW0-zy-SZf" secondAttribute="centerY" id="G82-qj-4Dh"/>
<constraint firstItem="okn-C5-YbU" firstAttribute="centerY" secondItem="aW0-zy-SZf" secondAttribute="centerY" id="YcG-R5-5mU"/>
</constraints>
<connections>
<outlet property="textField" destination="RL3-7c-bnu" id="9Bv-gF-NHv"/>
<outlet property="titleLabel" destination="TgL-rR-nuf" id="xJs-ev-q9x"/>
</connections>
<point key="canvasLocation" x="235.11450381679387" y="46.83098591549296"/>
</tableViewCell>
</objects>
<resources>
<image name="arrowRight" width="16" height="16"/>
</resources>
</document>

View File

@@ -0,0 +1,42 @@
//
// QXUserInfoEditFooterView.h
// QXLive
//
// Created by 启星 on 2025/5/20.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@protocol QXUserInfoImageCellDelegate <NSObject>
@optional
-(void)didClickDelete:(NSString*)imageUrl index:(NSInteger)index;
/// 图片上传完成
-(void)didUploadFinishedWithImageUrlList:(NSArray*)urlList;
@end
@interface QXUserInfoEditFooterView : UIView
/// 隐藏头 默认不隐藏
@property (nonatomic,assign)BOOL hideTitle;
/// 最大可选择张数 默认6张
@property (nonatomic,assign)NSInteger maxCount;
@property (nonatomic,weak)id<QXUserInfoImageCellDelegate>delegate;
/// 编辑资料时显示传值
@property (nonatomic,strong)NSArray *imgs;
@end
@interface QXUserInfoImageCell : UICollectionViewCell
@property (nonatomic,strong)UIImageView *imageView;
@property (nonatomic,strong)UIButton *deleteBtn;
@property (nonatomic,strong)NSString *imageUrl;
@property (nonatomic,assign)NSInteger index;
@property (nonatomic,weak)id<QXUserInfoImageCellDelegate>delegate;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,359 @@
//
// QXUserInfoEditFooterView.m
// QXLive
//
// Created by on 2025/5/20.
//
#import "QXUserInfoEditFooterView.h"
#import <TZImagePickerController/TZImageManager.h>
#import <TZImagePickerController/TZImagePickerController.h>
#import "UIImage+QX.h"
#import "NSString+QX.h"
#import "QXOSSManager.h"
#import "YBImageBrowser/YBImageBrowser.h"
@class QXUserInfoImageCell;
@interface QXUserInfoEditFooterView()<UICollectionViewDelegate,UICollectionViewDataSource,TZImagePickerControllerDelegate,QXUserInfoImageCellDelegate>
@property (nonatomic,strong)UILabel *titleLabel;
@property (nonatomic,strong)UICollectionView *collectionView;
@property (nonatomic,strong)NSMutableArray *dataArray;
@property (nonatomic,strong)NSMutableArray *keyArray;
@property (nonatomic,strong)NSMutableArray *urlArray;
@property (nonatomic,strong)NSMutableArray *selectedAssets;
@property (nonatomic,strong)NSMutableArray *selectedPhotos;
@end
@implementation QXUserInfoEditFooterView
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self initSubviews];
}
return self;
}
-(void)initSubviews{
self.maxCount = 6;
[self.urlArray addObject:@"mine_room_cover_add"];
self.titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(16, 12, self.width-32, 24)];
NSString *maxStr = [NSString stringWithFormat:@"(%@)",QXText(@"最多上传6张")];
NSString *str = [NSString stringWithFormat:@"%@%@",QXText(@"背景图片"),maxStr];
NSMutableAttributedString *attr = [[NSMutableAttributedString alloc] initWithString:str];
[attr yy_setFont:[UIFont systemFontOfSize:16] range:[str rangeOfString:QXText(@"背景图片")]];
[attr yy_setFont:[UIFont systemFontOfSize:12] range:[str rangeOfString:maxStr]];
[attr yy_setColor:QXConfig.textColor range:[str rangeOfString:QXText(@"背景图片")]];
[attr yy_setColor:RGB16(0x666666) range:[str rangeOfString:maxStr]];
self.titleLabel.attributedText = attr;
[self addSubview:self.titleLabel];
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.minimumLineSpacing = 20;
layout.minimumInteritemSpacing = 20;
int itemWidth = (self.width-16*2-20*2)/3;
layout.itemSize = CGSizeMake(itemWidth, itemWidth);
layout.sectionInset = UIEdgeInsetsMake(0, 16, 0, 16);
self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, self.titleLabel.bottom+6, self.width, self.height-self.titleLabel.bottom-6) collectionViewLayout:layout];
self.collectionView.scrollEnabled = NO;
self.collectionView.backgroundColor = [UIColor clearColor];
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
[self.collectionView registerClass:[QXUserInfoImageCell class] forCellWithReuseIdentifier:@"QXUserInfoImageCell"];
[self addSubview:self.collectionView];
}
-(void)setHideTitle:(BOOL)hideTitle{
_hideTitle = hideTitle;
if (hideTitle) {
self.titleLabel.hidden = YES;
self.collectionView.frame = CGRectMake(0, 12, self.width, self.height-24);
}
}
-(void)setImgs:(NSArray *)imgs{
_imgs = imgs;
[self.urlArray removeAllObjects];
[self.urlArray addObjectsFromArray:imgs];
if (_imgs.count < 6) {
[self.urlArray addObject:@"mine_room_cover_add"];
}
[self.collectionView reloadData];
}
-(void)setMaxCount:(NSInteger)maxCount{
_maxCount = maxCount;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return self.urlArray.count;
}
-(__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
QXUserInfoImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"QXUserInfoImageCell" forIndexPath:indexPath];
cell.imageUrl = self.urlArray[indexPath.row];
cell.delegate = self;
cell.index = indexPath.row;
return cell;
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
NSString *imageUrl = self.urlArray[indexPath.row];
if ([imageUrl hasPrefix:@"http"] || [imageUrl hasPrefix:@"https"]) {
if (self.imgs != nil) {
YBImageBrowser *browser = [YBImageBrowser new];
NSMutableArray *sourceArray = [NSMutableArray array];
for (NSString *url in self.urlArray) {
if ([url hasPrefix:@"http"] || [url hasPrefix:@"https"]) {
YBIBImageData *data = [[YBIBImageData alloc] init];
data.imageURL = [NSURL URLWithString:url];
QXUserInfoImageCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
data.projectiveView = cell.imageView;
[sourceArray addObject:data];
}
}
browser.dataSourceArray = sourceArray;
browser.currentPage = indexPath.row;
[browser show];
}else{
TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithSelectedAssets:self.selectedAssets selectedPhotos:self.selectedPhotos index:indexPath.item];
imagePickerVc.maxImagesCount = self.maxCount;
imagePickerVc.allowPickingGif = NO;
imagePickerVc.autoSelectCurrentWhenDone = NO;
imagePickerVc.allowPickingOriginalPhoto = NO;
imagePickerVc.allowPickingMultipleVideo = NO;
imagePickerVc.showSelectedIndex = YES;
imagePickerVc.isSelectOriginalPhoto = NO;
imagePickerVc.modalPresentationStyle = UIModalPresentationFullScreen;
[imagePickerVc setDidFinishPickingPhotosHandle:^(NSArray<UIImage *> *photos, NSArray *assets, BOOL isSelectOriginalPhoto) {
self->_selectedAssets = [NSMutableArray arrayWithArray:assets];
[self->_collectionView reloadData];
}];
[self.viewController presentViewController:imagePickerVc animated:YES completion:nil];
}
}else{
if (self.imgs != nil) {
self.maxCount = 7 - self.urlArray.count ;
}
[self selectAlbumPhoto];
}
}
-(void)didClickDelete:(NSString *)imageUrl index:(NSInteger)index{
if (self.imgs != nil) {
[self.urlArray removeObjectAtIndex:index];
if (![self.urlArray.lastObject isEqualToString:@"mine_room_cover_add"]) {
[self.urlArray addObject:@"mine_room_cover_add"];
}
[self.collectionView reloadData];
if (self.delegate && [self.delegate respondsToSelector:@selector(didClickDelete:index:)]) {
[self.delegate didClickDelete:imageUrl index:index];
}
}else{
NSInteger index = [self.urlArray indexOfObject:imageUrl];
[self.dataArray removeObjectAtIndex:index];
[self.keyArray removeObjectAtIndex:index];
[self.selectedAssets removeObjectAtIndex:index];
[self.selectedPhotos removeObjectAtIndex:index];
[self.urlArray removeObjectAtIndex:index];
if (![self.urlArray.lastObject isEqualToString:@"mine_room_cover_add"]) {
[self.urlArray addObject:@"mine_room_cover_add"];
}
[self.collectionView reloadData];
}
}
-(void)selectAlbumPhoto {
TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:self.maxCount columnNumber:4 delegate:self pushPhotoPickerVc:YES];
imagePickerVc.maxImagesCount = self.maxCount;
imagePickerVc.allowCameraLocation = NO;
imagePickerVc.allowPickingOriginalPhoto = NO;
if (self.imgs == nil) {
if (self.selectedAssets.count>0) {
imagePickerVc.selectedAssets = self.selectedAssets;
}
}
imagePickerVc.showSelectedIndex = YES;
imagePickerVc.allowTakeVideo = NO;
imagePickerVc.allowPickingVideo = NO;
imagePickerVc.showSelectBtn = NO;
imagePickerVc.allowCrop = NO;
imagePickerVc.allowPickingGif = NO;
MJWeakSelf
[imagePickerVc setDidFinishPickingPhotosHandle:^(NSArray<UIImage *> *photos, NSArray *assets, BOOL isSelectOriginalPhoto) {
[weakSelf.dataArray removeAllObjects];
[weakSelf.keyArray removeAllObjects];
for (int i = 0 ;i < assets.count ;i ++) {
PHAsset*asset = assets[i];
[[TZImageManager manager] getOriginalPhotoDataWithAsset:asset completion:^(NSData *data, NSDictionary *info, BOOL isDegraded) {
// NSString *imageType = [NSString contentTypeWithImageData:data];
// NSData *imgData = data;
// if ([imageType isEqualToString:@"HEIC"] || [imageType isEqualToString:@"HEIF"] || [imageType isEqualToString:@"tiff"] || [imageType isEqualToString:@"webp"]) {
UIImage *dataImg = [UIImage imageWithData:data];
NSData *imgData = UIImageJPEGRepresentation(dataImg, 0.5);
// }
[weakSelf.dataArray addObject:imgData];
[weakSelf.keyArray addObject:[weakSelf imagePathWithKey:[NSString contentTypeWithImageData:imgData]]];
if (weakSelf.dataArray.count == assets.count) {
[weakSelf OSSUploadPhoto];
}
}];
[self.selectedAssets removeAllObjects];
[self.selectedAssets addObjectsFromArray:assets];
[self.selectedPhotos removeAllObjects];
[self.selectedPhotos addObjectsFromArray:photos];
}
}];
imagePickerVc.modalPresentationStyle = UIModalPresentationFullScreen;
[imagePickerVc.navigationBar setBackgroundImage:[UIImage qx_imageWithColor:RGB16(0x333333)] forBarMetrics:UIBarMetricsDefault];
[self.viewController presentViewController:imagePickerVc animated:YES completion:nil];
}
- (void)OSSUploadPhoto{
__weak typeof(self)weakSelf = self;
showLoadingInView(self.viewController.view);
[[QXOSSManager sharedInstance] activityUploadFile:self.dataArray withObjectKey:self.keyArray isAsync:YES complete:^(NSArray<NSString *> *names, UploadImageState state) {
dispatch_async_and_wait(dispatch_get_main_queue(), ^{
hideLoadingInView(weakSelf.viewController.view);
if (state == UploadImageSuccess) {
showToast(QXText(@"上传成功"));
if (self.imgs == nil) {
[weakSelf.urlArray removeAllObjects];
if (names.count < self.maxCount) {
for (NSString*fileName in names) {
NSString *fileUrl =[NSString stringWithFormat:@"https://%@.%@/%@",OSS_BUCKET_NAME,OSSEndPoint,fileName];
[weakSelf.urlArray addObject:fileUrl];
}
[weakSelf.urlArray addObject:@"mine_room_cover_add"];
}else if (names.count == self.maxCount){
for (NSString*fileName in names) {
NSString *fileUrl =[NSString stringWithFormat:@"https://%@.%@/%@",OSS_BUCKET_NAME,OSSEndPoint,fileName];
[weakSelf.urlArray addObject:fileUrl];
}
}else{
for (int i = 0; i < self.maxCount; i++) {
NSString *name = names[i];
NSString *fileUrl =[NSString stringWithFormat:@"https://%@.%@/%@",OSS_BUCKET_NAME,OSSEndPoint,name];
[weakSelf.urlArray addObject:fileUrl];
}
}
[weakSelf uploadImgs];
}else{
NSMutableArray *arr = [NSMutableArray array];
for (NSString*fileName in names) {
NSString *fileUrl =[NSString stringWithFormat:@"https://%@.%@/%@",OSS_BUCKET_NAME,OSSEndPoint,fileName];
[weakSelf.urlArray insertObject:fileUrl atIndex:0];
[arr addObject:fileUrl];
}
[weakSelf uploadImgs:arr];
}
}else{
showToast(QXText(@"上传失败"));
}
});
}];
}
- (NSString *)imagePathWithKey:(NSString *)keyPath {
NSString *fileBasePath = IMG_FILE_BASE_PATH;
return [NSString stringWithFormat:@"%@%@/%@.%@",fileBasePath,[[QXOSSManager sharedInstance] currentDate],[NSUUID UUID].UUIDString,keyPath];
}
-(void)uploadImgs{
[self.collectionView reloadData];
if (self.delegate && [self.delegate respondsToSelector:@selector(didUploadFinishedWithImageUrlList:)]) {
NSMutableArray *arr = [NSMutableArray arrayWithArray:self.urlArray];
if ([arr containsObject:@"mine_room_cover_add"]) {
[arr removeObject:@"mine_room_cover_add"];
}
[self.delegate didUploadFinishedWithImageUrlList:arr];
}
}
-(void)uploadImgs:(NSArray*)imgs{
[self.collectionView reloadData];
if (self.delegate && [self.delegate respondsToSelector:@selector(didUploadFinishedWithImageUrlList:)]) {
[self.delegate didUploadFinishedWithImageUrlList:imgs];
}
}
-(NSMutableArray *)dataArray{
if (!_dataArray) {
_dataArray = [NSMutableArray array];
}
return _dataArray;
}
- (NSMutableArray *)keyArray{
if (!_keyArray) {
_keyArray = [NSMutableArray array];
}
return _keyArray;
}
-(NSMutableArray *)urlArray{
if (!_urlArray) {
_urlArray = [NSMutableArray array];
}
return _urlArray;
}
-(NSMutableArray *)selectedAssets{
if (!_selectedAssets) {
_selectedAssets = [NSMutableArray array];
}
return _selectedAssets;
}
-(NSMutableArray *)selectedPhotos{
if (!_selectedPhotos) {
_selectedPhotos = [NSMutableArray array];
}
return _selectedPhotos;
}
@end
@implementation QXUserInfoImageCell
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self initSubviews];
}
return self;
}
-(void)setImageUrl:(NSString *)imageUrl{
_imageUrl = imageUrl;
if ([imageUrl hasPrefix:@"http"] || [imageUrl hasPrefix:@"https"]) {
self.deleteBtn.hidden = NO;
[self.imageView sd_setImageWithURL:[NSURL URLWithString:imageUrl] placeholderImage:nil];
}else{
if ([imageUrl isEqualToString:@"mine_room_cover_add"]) {
self.imageView.image = [UIImage imageNamed:imageUrl];
self.deleteBtn.hidden = YES;
}else{
NSString *fileUrl =[NSString stringWithFormat:@"https://%@.%@/%@",OSS_BUCKET_NAME,OSSEndPoint,imageUrl];
[self.imageView sd_setImageWithURL:[NSURL URLWithString:fileUrl] placeholderImage:nil];
self.deleteBtn.hidden = NO;
}
}
}
-(void)initSubviews{
self.imageView = [[UIImageView alloc] init];
[self.contentView addSubview:self.imageView];
self.imageView.contentMode = UIViewContentModeScaleAspectFill;
self.imageView.clipsToBounds = YES;
[self.imageView addRoundedCornersWithRadius:10];
[self.imageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.bottom.left.right.equalTo(self.contentView);
}];
self.deleteBtn = [[UIButton alloc] init];
[self.deleteBtn addTarget:self action:@selector(deleteAction:) forControlEvents:(UIControlEventTouchUpInside)];
[self.deleteBtn setImage:[UIImage imageNamed:@"Plus Circle"] forState:(UIControlStateNormal)];
[self.contentView addSubview:self.deleteBtn];
[self.deleteBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.top.equalTo(self);
make.size.mas_equalTo(CGSizeMake(25, 25));
}];
}
-(void)deleteAction:(UIButton*)sender{
if (self.delegate && [self.delegate respondsToSelector:@selector(didClickDelete:index:)]) {
[self.delegate didClickDelete:self.imageUrl index:self.index];
}
}
@end

View File

@@ -0,0 +1,22 @@
//
// QXUserInfoEditHeaderView.h
// QXLive
//
// Created by 启星 on 2025/5/20.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@protocol QXUserInfoEditHeaderViewDelegate <NSObject>
@optional
-(void)didClickHeader;
@end
@interface QXUserInfoEditHeaderView : UIView
@property (nonatomic,weak)id<QXUserInfoEditHeaderViewDelegate>delegate;
@property (nonatomic,strong)NSArray *imgs;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,175 @@
//
// QXUserInfoEditHeaderView.m
// QXLive
//
// Created by on 2025/5/20.
//
#import "QXUserInfoEditHeaderView.h"
#import <SDCycleScrollView/SDCycleScrollView.h>
#import "QXSeatHeaderView.h"
#import "UIButton+QX.h"
#import <TZImagePickerController/TZImageManager.h>
#import <TZImagePickerController/TZImagePickerController.h>
#import "UIImage+QX.h"
#import "NSString+QX.h"
#import "QXOSSManager.h"
#import <ImSDK_Plus/ImSDK_Plus.h>
#import "QXMineNetwork.h"
@interface QXUserInfoEditHeaderView()<SDCycleScrollViewDelegate,TZImagePickerControllerDelegate>
@property (nonatomic,strong)SDCycleScrollView * cycleScrollView;
@property (nonatomic,strong) QXSeatHeaderView* headerView;
@property (nonatomic,strong) UIButton* headerBtn;
@property (nonatomic,strong) UIView * bgView;
@property (nonatomic,strong) UILabel * titleLabel;
@property (nonatomic,strong) NSString * avartar;
@end
@implementation QXUserInfoEditHeaderView
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self initSubviews];
}
return self;
}
-(void)initSubviews{
self.cycleScrollView = [SDCycleScrollView cycleScrollViewWithFrame:CGRectMake(0, 0, self.width, 169+kSafeAreaTop+16) delegate:self placeholderImage:nil];
self.cycleScrollView.backgroundColor = QXConfig.themeColor;
self.cycleScrollView.imageURLStringsGroup = @[[QXGlobal shareGlobal].loginModel.avatar?[QXGlobal shareGlobal].loginModel.avatar:@""];
self.cycleScrollView.bannerImageViewContentMode = UIViewContentModeScaleAspectFill;
[self addSubview:self.cycleScrollView];
self.bgView = [[UIView alloc] initWithFrame:CGRectMake(0, self.cycleScrollView.bottom-16, self.width, 94)];
self.bgView.backgroundColor = [UIColor whiteColor];
[self.bgView addRoundedCornersWithRadius:16 byRoundingCorners:(UIRectCornerTopLeft|UIRectCornerTopRight)];
[self addSubview:self.bgView];
self.titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(80, self.bgView.height-40, self.bgView.width-160, 40)];
self.titleLabel.font = [UIFont systemFontOfSize:12];
self.titleLabel.numberOfLines = 2;
self.titleLabel.textColor = RGB16(0x999999);
self.titleLabel.text = QXText(@"尊敬的用户每月可修改2次剩余2次 使用头像卡不限更换次数还剩0张");
[self.bgView addSubview:self.titleLabel];
self.headerView = [[QXSeatHeaderView alloc] initWithFrame:CGRectMake((self.width-104)/2, self.bgView.top-52, 104, 104)];
self.headerView.layer.borderWidth = 1.5;
self.headerView.layer.borderColor = UIColor.whiteColor.CGColor;
[self.headerView addRoundedCornersWithRadius:52];
[self.headerView setHeadIcon:[QXGlobal shareGlobal].loginModel.avatar dress:@""];
[self addSubview:self.headerView];
self.headerBtn = [[UIButton alloc] initWithFrame:CGRectMake((self.width-100)/2, self.headerView.top+2, 100, 100)];
[self.headerBtn addRoundedCornersWithRadius:52];
self.headerBtn.backgroundColor = RGB16A(0x333333, 0.22);
[self.headerBtn setImage:[UIImage imageNamed:@"userinfo_header_edit"] forState:(UIControlStateNormal)];
[self.headerBtn setTitle:QXText(@"更换头像") forState:(UIControlStateNormal)];
self.headerBtn.titleLabel.font = [UIFont systemFontOfSize:14];
[self.headerBtn setTitleColor:[UIColor whiteColor] forState:(UIControlStateNormal)];
[self.headerBtn addTarget:self action:@selector(headerAction) forControlEvents:(UIControlEventTouchUpInside)];
[self.headerBtn qx_layoutButtonNOSizeToFitWithEdgeInsetsStyle:(QXButtonEdgeInsetsStyleTop) imageTitleSpace:2];
[self addSubview:self.headerBtn];
}
-(void)headerAction{
[self selectAlbumPhoto];
}
-(void)setImgs:(NSArray *)imgs{
_imgs = imgs;
if (imgs.count == 0) {
self.cycleScrollView.imageURLStringsGroup = @[[QXGlobal shareGlobal].loginModel.avatar?[QXGlobal shareGlobal].loginModel.avatar:@""];
}else{
self.cycleScrollView.imageURLStringsGroup = imgs;
}
}
-(void)selectAlbumPhoto {
TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:1 delegate:nil];
imagePickerVc.maxImagesCount = 1;
imagePickerVc.allowCameraLocation = NO;
imagePickerVc.allowPickingOriginalPhoto = NO;
imagePickerVc.allowTakeVideo = NO;
imagePickerVc.allowPickingVideo = NO;
imagePickerVc.showSelectBtn = NO;
imagePickerVc.allowCrop = YES;
imagePickerVc.cropRect = CGRectMake(0, (SCREEN_HEIGHT-SCREEN_WIDTH)/2, SCREEN_WIDTH, SCREEN_WIDTH);
MJWeakSelf
[imagePickerVc setDidFinishPickingPhotosHandle:^(NSArray<UIImage *> *photos, NSArray *assets, BOOL isSelectOriginalPhoto) {
if (photos.count) {
NSData *imageData = [photos.firstObject qx_compressImageQualityWithToByte:(SCREEN_WIDTH*SCREEN_HEIGHT*2)];
[weakSelf OSSUploadPhotoWithFileData:imageData contentType:[NSString contentTypeWithImageData:imageData]];
}
}];
imagePickerVc.modalPresentationStyle = UIModalPresentationFullScreen;
[imagePickerVc.navigationBar setBackgroundImage:[UIImage qx_imageWithColor:RGB16(0x333333)] forBarMetrics:UIBarMetricsDefault];
[self.viewController presentViewController:imagePickerVc animated:YES completion:nil];
}
- (void)OSSUploadPhotoWithFileData:(NSData *)fileData contentType:(NSString *)contentType {
[self OSSUploadPhotoWithFileData:fileData contentType:contentType isVideoCover:NO];
}
- (void)OSSUploadPhotoWithFileData:(NSData *)fileData contentType:(NSString *)contentType isVideoCover:(BOOL)isVideoCover {
if (!fileData || !contentType) {
showToastInView(QXText(@"资源加载错误"), self.viewController.view);
return;
}
if (fileData.length > 1024*1024 && [contentType isEqualToString:IMG_FILE_BASE_PATH]) {
showToastInView(QXText(@"请不要上传超过1M的头像"), self.viewController.view);
return;
}
NSMutableArray *files = [[NSMutableArray alloc] initWithObjects:fileData, nil];
NSString *fileBasePath = IMG_FILE_BASE_PATH;//
NSString *fileName = [NSString stringWithFormat:@"%@%@/%@.%@",fileBasePath,[[QXOSSManager sharedInstance] currentDate],[NSUUID UUID].UUIDString,contentType];
NSMutableArray *fileNames = [[NSMutableArray alloc] initWithObjects:fileName, nil];
__weak typeof(self)weakSelf = self;
showLoadingInView(self.viewController.view);
[[QXOSSManager sharedInstance] uploadFile:files withObjectKey:fileNames isAsync:YES complete:^(NSArray<NSString *> *names, UploadImageState state) {
dispatch_async(dispatch_get_main_queue(), ^{
hideLoadingInView(weakSelf.viewController.view);
});
if (state == UploadImageSuccess) {
NSString *fileName = [names lastObject];
NSString *fileUrl =[NSString stringWithFormat:@"https://%@.%@/%@",OSS_BUCKET_NAME,OSSEndPoint,fileName];
weakSelf.avartar = fileUrl;
[weakSelf chamgeAvatar];
}else{
showToastInView(QXText(@"文件上传失败,请重新尝试"), weakSelf.viewController.view);
}
}];
}
-(void)chamgeAvatar{
MJWeakSelf
[QXMineNetwork editUserInfoWithNickname:@""
birthday:@""
sex:@""
avatar:self.avartar
images:@""
profile:@""
tag_id:@""
successBlock:^(NSDictionary * _Nonnull dict) {
///
[QXGlobal shareGlobal].loginModel.avatar = weakSelf.avartar;
[weakSelf.headerView.headImageView sd_setImageWithURL:[NSURL URLWithString:weakSelf.avartar]];
[[QXGlobal shareGlobal] updateUserInfoWithMolde:[QXGlobal shareGlobal].loginModel];
if (weakSelf.imgs.count == 0) {
weakSelf.cycleScrollView.imageURLStringsGroup = @[[QXGlobal shareGlobal].loginModel.avatar];
}
///
V2TIMUserFullInfo *info = [[V2TIMUserFullInfo alloc] init];
info.faceURL = weakSelf.avartar;
info.nickName = [QXGlobal shareGlobal].loginModel.nickname;
[[V2TIMManager sharedInstance] setSelfInfo:info succ:^{
QXLOG(@"腾讯IM同步个人信息成功");
} fail:^(int code, NSString * _Nullable desc) {
QXLOG(@"腾讯IM同步个人信息失败");
}];
showToast(QXText(@"修改成功"));
} failBlock:^(NSError * _Nonnull error, NSString * _Nonnull msg) {
showToast(msg);
}];
}
@end