# MSDemo **Repository Path**: mlsRepository/MSDemo ## Basic Information - **Project Name**: MSDemo - **Description**: 基础框架 - **Primary Language**: Objective-C - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2021-06-23 - **Last Updated**: 2024-11-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # MSDemo #### 介绍 基础框架 采用CocoaPods 管理第三方 #### 目录结构 ├── Base // 基类 ├── Category // 类别 ├── Main // 项目入口 │ ├── main.json // 项目功能模块配置JSON文件 ├── Resource // 项目资源 ├── Sections // 项目功能模块,项目代码主要在这个文件下编写 │ ├── 功能模块1 │ ├── 功能模块2 │ ├── 功能模块3 │ ├── 功能模块4 ├── Support // 项目支持 │ ├── MSChain // 链式编程 │ ├── WebView // web │ ├── MSUncaughtExceptionHandler // 捕获异常 │ ├── Macro // 宏 │ │ ├── ApiURLConfig.h // 接口URL │ │ ├── MSMacro.h // 常用宏 │ ├── MSAreaPickerView // 省市区选择器 │ ├── MSFPS // FPS │ ├── MSKeyBoardTool // 键盘工具(遮挡自动上移,inputAccessoryView) │ ├── MSNetworking // 基于AF的网络请求 │ ├── MSPasswordView // 密码输入/设置 │ ├── MSDemo.pch // pch #### 项目规范 * 命名规则 * 文件夹:大驼峰命名规则 * 文件:小驼峰命名规则 * 图片资源:功能模块_功能,如 tabBar_home_selected #### 使用说明 1. YBImageBrowsers使用 ``` NSMutableArray *datas = [NSMutableArray array]; // 网络视频 YBIBVideoData *data = [YBIBVideoData new]; data.videoURL = [NSURL URLWithString:[self picUrl:self.shopInfoViewModel.shopInfo.video]]; data.projectiveView = imageView; [datas addObject:data]; //图片 YBIBImageData *data = [YBIBImageData new]; data.imageURL = [NSURL URLWithString:[self picUrl:self.picArray[i]]]; data.projectiveView = imageView; [datas addObject:data]; YBImageBrowser *browser = [YBImageBrowser new]; browser.dataSourceArray = datas; browser.currentPage = recognizer.view.tag - 200; [browser show]; ``` 2. HXPhotoPicker使用 ###### 选取 ``` // 懒加载 照片管理类 - (HXPhotoManager *)manager { if (!_manager) { _manager = [[HXPhotoManager alloc] initWithType:HXPhotoManagerSelectedTypePhotoAndVideo]; _manager.configuration.photoMaxNum = 1; _manager.configuration.type = HXConfigurationTypeWXChat; // _manager.configuration.limitPhotoSize = 1 * 1024 * 1024; _manager.configuration.singleSelected = YES; _manager.configuration.lookGifPhoto = NO; _manager.configuration.singleJumpEdit = YES; _manager.configuration.photoEditConfigur.onlyCliping = YES; _manager.configuration.photoEditConfigur.aspectRatio = HXPhotoEditAspectRatioType_Custom; _manager.configuration.photoEditConfigur.customAspectRatio = CGSizeMake(1, 1); } return _manager; } ``` ``` #pragma mark - HXPhotoViewDelegate - (void)photoView:(HXPhotoView *)photoView changeComplete:(NSArray *)allList photos:(NSArray *)photos videos:(NSArray *)videos original:(BOOL)isOriginal { if (!kArrayIsEmpty(photos)) { HXPhotoModel *photoModel = photos.firstObject; [photoModel getImageWithSuccess:^(UIImage * _Nullable image, HXPhotoModel * _Nullable model, NSDictionary * _Nullable info) { self.headView.image = image; self.photoModel = model; } failed:^(NSDictionary * _Nullable info, HXPhotoModel * _Nullable model) { [self showHudWithMessage:@"选取照片失败" mode:MBProgressHUDModeText autoHide:YES]; }]; } else if (!kArrayIsEmpty(videos)) { HXPhotoModel *photoModel = videos.firstObject; // 获取当前资源图片 [photoModel getImageWithSuccess:^(UIImage * _Nullable image, HXPhotoModel * _Nullable model, NSDictionary * _Nullable info) { self.headView.image = image; self.photoModel = model; } failed:^(NSDictionary * _Nullable info, HXPhotoModel * _Nullable model) { [self showHudWithMessage:@"选取照片失败" mode:MBProgressHUDModeText autoHide:YES]; }]; // 获取当前资源的URL [photoModel getAssetURLWithVideoPresetName:AVAssetExportPresetMediumQuality success:^(NSURL * _Nullable URL, HXPhotoModelMediaSubType mediaType, BOOL isNetwork, HXPhotoModel * _Nullable model) { // 导出成功 self.photoURL = URL; } failed:^(NSDictionary * _Nullable info, HXPhotoModel * _Nullable model) { // 导出失败 }]; } } #pragma mark - HXCustomNavigationControllerDelegate // 通过 HXCustomNavigationControllerDelegate 代理返回选择的图片以及视频 /** 点击完成按钮 @param photoNavigationViewController self @param allList 已选的所有列表(包含照片、视频) @param photoList 已选的照片列表 @param videoList 已选的视频列表 @param original 是否原图 */ - (void)photoNavigationViewController:(HXCustomNavigationController *)photoNavigationViewController didDoneAllList:(NSArray *)allList photos:(NSArray *)photoList videos:(NSArray *)videoList original:(BOOL)original { if (!kArrayIsEmpty(photoList)) { HXPhotoModel *photoModel = photoList.firstObject; [photoModel getImageWithSuccess:^(UIImage * _Nullable image, HXPhotoModel * _Nullable model, NSDictionary * _Nullable info) { self.headView.image = image; self.photoModel = model; } failed:^(NSDictionary * _Nullable info, HXPhotoModel * _Nullable model) { [self showHudWithMessage:@"选取照片失败" mode:MBProgressHUDModeText autoHide:YES]; }]; } else if (!kArrayIsEmpty(videoList)) { HXPhotoModel *photoModel = videoList.firstObject; // 获取当前资源图片 [photoModel getImageWithSuccess:^(UIImage * _Nullable image, HXPhotoModel * _Nullable model, NSDictionary * _Nullable info) { self.headView.image = image; self.photoModel = model; } failed:^(NSDictionary * _Nullable info, HXPhotoModel * _Nullable model) { [self showHudWithMessage:@"选取照片失败" mode:MBProgressHUDModeText autoHide:YES]; }]; // 获取当前资源的URL [photoModel getAssetURLWithVideoPresetName:AVAssetExportPresetMediumQuality success:^(NSURL * _Nullable URL, HXPhotoModelMediaSubType mediaType, BOOL isNetwork, HXPhotoModel * _Nullable model) { // 导出成功 self.photoURL = URL; } failed:^(NSDictionary * _Nullable info, HXPhotoModel * _Nullable model) { // 导出失败 }]; } } /** 点击取消 @param photoNavigationViewController self */ - (void)photoNavigationViewControllerDidCancel:(HXCustomNavigationController *)photoNavigationViewController { [self showHudWithMessage:@"取消" mode:MBProgressHUDModeText autoHide:YES]; } ``` ``` /** 选择照片 */ - (void)choosePhoto { UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"修改头像" message:@"" preferredStyle:UIAlertControllerStyleActionSheet]; if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { [alertController addAction:[UIAlertAction actionWithTitle:@"拍照" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { [self.view addSubview:self.photoView]; [self.photoView goCameraViewController]; }]]; } [alertController addAction:[UIAlertAction actionWithTitle:@"我的相册" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { // 照片选择控制器 HXCustomNavigationController *nav = [[HXCustomNavigationController alloc] initWithManager:self.manager delegate:self]; [self presentViewController:nav animated:YES completion:nil]; }]]; [alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]]; [self presentViewController:alertController animated:YES completion:nil]; } ``` ###### 预览图片 ``` - (void)previewPhoto { HXWeakSelf if (!self.headView.image) return; [self showAlert:@"提示" message:@"是否编辑" messageAlignment:NSTextAlignmentCenter leftAction:[UIAlertAction actionWithTitle:@"是" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { HXPhotoEditConfiguration *configuration = self.manager.configuration.photoEditConfigur; if (self.photoModel.type == HXPhotoModelMediaTypeVideo || self.photoModel.type == HXPhotoModelMediaTypeCameraVideo) { //单独使用视频编辑功能 [self hx_presentVideoEditViewControllerWithManager:self.manager videoModel:self.photoModel delegate:nil done:^(HXPhotoModel *beforeModel, HXPhotoModel *afterModel, HXVideoEditViewController *viewController) { // beforeModel编辑之前、afterModel编辑之后 weakSelf.headView.image = afterModel.thumbPhoto; } cancel:^(HXVideoEditViewController *viewController) { // 取消 }]; } else { // 单独使用仿微信编辑功能 [self hx_presentWxPhotoEditViewControllerWithConfiguration:configuration photoModel:self.photoModel delegate:nil finish:^(HXPhotoEdit * _Nonnull photoEdit, HXPhotoModel * _Nonnull photoModel, HX_PhotoEditViewController * _Nonnull viewController) { if (photoEdit) { // 有编辑过 weakSelf.headView.image = photoEdit.editPreviewImage; }else { // 为空则未进行编辑 weakSelf.headView.image = photoModel.thumbPhoto; } // 记录下当前编辑的记录,再次编辑可在上一次基础上进行编辑 // weakSelf.photoEdit = photoEdit; } cancel:^(HX_PhotoEditViewController * _Nonnull viewController) { // 取消 }]; } }] rightAction:[UIAlertAction actionWithTitle:@"否" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { //单独使用HXPhotoPreviewViewController预览图片 if (self.photoModel.type == HXPhotoModelMediaTypeVideo || self.photoModel.type == HXPhotoModelMediaTypeCameraVideo) { if (self.photoURL) { HXCustomAssetModel *assetModel = [HXCustomAssetModel assetWithLocalVideoURL:self.photoURL selected:YES]; [self presentPreviewPhotoController:@[assetModel]]; } else { [self showHudWithMessage:@"资源的URL尚未导出成功,请稍后再预览" mode:MBProgressHUDModeText autoHide:YES]; } } else { HXCustomAssetModel *assetModel = [HXCustomAssetModel assetWithLocalImage:self.headView.image selected:YES]; [self presentPreviewPhotoController:@[assetModel]]; } }]]; } - (void)presentPreviewPhotoController:(NSArray *)assetModels { HXWeakSelf HXPhotoManager *photoManager = [HXPhotoManager managerWithType:HXPhotoManagerSelectedTypePhotoAndVideo]; photoManager.configuration.saveSystemAblum = YES; photoManager.configuration.photoMaxNum = 0; photoManager.configuration.videoMaxNum = 0; photoManager.configuration.maxNum = 10; photoManager.configuration.selectTogether = YES; photoManager.configuration.photoCanEdit = YES; photoManager.configuration.videoCanEdit = YES; // 长按事件 photoManager.configuration.previewRespondsToLongPress = ^(UILongPressGestureRecognizer *longPress, HXPhotoModel *photoModel, HXPhotoManager *manager, HXPhotoPreviewViewController *previewViewController) { hx_showAlert(previewViewController, @"提示", @"长按事件", @"确定", nil, nil, nil); }; // 跳转预览界面时动画起始的view photoManager.configuration.customPreviewFromView = ^UIView *(NSInteger currentIndex) { HXPhotoSubViewCell *viewCell = [weakSelf.photoView collectionViewCellWithIndex:currentIndex]; return viewCell; }; // 跳转预览界面时展现动画的image photoManager.configuration.customPreviewFromImage = ^UIImage *(NSInteger currentIndex) { HXPhotoSubViewCell *viewCell = [weakSelf.photoView collectionViewCellWithIndex:currentIndex]; return viewCell.imageView.image; }; // 退出预览界面时终点view photoManager.configuration.customPreviewToView = ^UIView *(NSInteger currentIndex) { HXPhotoSubViewCell *viewCell = [weakSelf.photoView collectionViewCellWithIndex:currentIndex]; return viewCell; }; [photoManager addCustomAssetModel:assetModels]; [self hx_presentPreviewPhotoControllerWithManager:photoManager previewStyle:HXPhotoViewPreViewShowStyleDark currentIndex:0 photoView:nil]; } ``` 3. YYLabel使用 ``` YYLabel *label = [[YYLabel alloc] init]; label.preferredMaxLayoutWidth = self.view.frame.size.width-85;//最大宽度 NSMutableAttributedString *attriStr = [[NSMutableAttributedString alloc] initWithString:@"测试协议《百度协议》《标签富文本》"]; // 设置不同字体颜色 [attriStr yy_setColor:[UIColor blueColor] range:[[attriStr string] rangeOfString:@"《百度协议》"]]; [attriStr yy_setColor:[UIColor redColor] range:[[attriStr string] rangeOfString:@"《标签富文本》"]]; // 方式一 [attriStr yy_setTextHighlightRange:[attriStr.string rangeOfString:@"《百度协议》"] color:[UIColor blueColor] backgroundColor:UIColor.clearColor userInfo:nil tapAction:^(UIView * _Nonnull containerView, NSAttributedString * _Nonnull text, NSRange range, CGRect rect) { NSLog(@"%@", [text.string substringWithRange:range]); MSWebViewController *webVC = [[MSWebViewController alloc] init]; webVC.ms_url = @"https:www.baidu.com"; webVC.hidesBottomBarWhenPushed = YES; [self.navigationController pushViewController:webVC animated:YES]; } longPressAction:^(UIView * _Nonnull containerView, NSAttributedString * _Nonnull text, NSRange range, CGRect rect) { NSLog(@"%@", [text.string substringWithRange:range]); }]; // 方式二 YYTextHighlight *highlight = [YYTextHighlight new]; [highlight setColor:[UIColor orangeColor]]; highlight.tapAction = ^(UIView *containerView, NSAttributedString *text, NSRange range, CGRect rect) { NSString *string = @"

测试测试

\"1622529221.png\"

测试测试的

"; MSWebViewController *webVC = [[MSWebViewController alloc] init]; webVC.ms_path = [string adaptWebViewForHtml]; webVC.hidesBottomBarWhenPushed = YES; [self.navigationController pushViewController:webVC animated:YES]; }; [attriStr yy_setTextHighlight:highlight range:[attriStr.string rangeOfString:@"《标签富文本》"]]; label.attributedText = attriStr; [self.view addSubview:label]; [label mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(_view.mas_bottom).offset(8); make.centerX.equalTo(_view); }]; ``` 4.