1、压缩与解压字符串(文件) 操作
实现对字符串进行压缩解压操作 前提需要导入libz.1.2.5.dylib 库
#import "BYViewController.h"
#import "zipAndUnzip.h"
@interface BYViewController ()
@end
@implementation BYViewController
- (void)viewDidLoad
{
[super viewDidLoad];
zipAndUnzip *zipAnd = [[zipAndUnzip alloc] init];
NSString *str = @"Hello.madison向显笑";
NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(NSUTF16BigEndianStringEncoding);
NSData *data = [str dataUsingEncoding:enc];
NSData *dataDeflate = [zipAnd gzipDeflate:data];
Byte *byte = (Byte *)[dataDeflate bytes];
for (int i=0 ; i<[dataDeflate length]; i++){
NSLog(@"byte = %d",byte[i]);
}
NSData *adata = [[NSData alloc] initWithBytes:byte length:[dataDeflate length]];
// NSData *dataInflate = [zipAnd gzipInflate:adata];
NSString *aString = [[NSString alloc] initWithData:adata encoding:enc];
NSLog(@"aString:%@",aString);
}
@end
@interface zipAndUnzip : NSObject
- (NSData *)gzipInflate:(NSData*)data;
- (NSData *)gzipDeflate:(NSData*)data;
@end
#import "zipAndUnzip.h"
#import "zlib.h"
@implementation zipAndUnzip
//解压缩
- (NSData *)gzipInflate:(NSData*)data
{
if ([data length] == 0) return data;
unsigned full_length = (int)[data length];
unsigned half_length = (int)[data length] / 2;
NSMutableData *decompressed = [NSMutableData dataWithLength: full_length + half_length];
BOOL done = NO;
int status;
z_stream strm;
strm.next_in = (Bytef *)[data bytes];
strm.avail_in = (int)[data length];
strm.total_out = 0;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
if (inflateInit2(&strm, (15+32)) != Z_OK)
return nil;
while (!done)
{
// Make sure we have enough room and reset the lengths.
if (strm.total_out >= [decompressed length])
[decompressed increaseLengthBy: half_length];
strm.next_out = [decompressed mutableBytes] + strm.total_out;
strm.avail_out = (uint)[decompressed length] - (uint)strm.total_out;
// Inflate another chunk.
status = inflate (&strm, Z_SYNC_FLUSH);
if (status == Z_STREAM_END)
done = YES;
else if (status != Z_OK)
break;
}
if (inflateEnd (&strm) != Z_OK)
return nil;
// Set real length.
if (done)
{
[decompressed setLength: strm.total_out];
return [NSData dataWithData: decompressed];
}
else return nil;
}
//压缩
- (NSData *)gzipDeflate:(NSData*)data
{
if ([data length] == 0) return data;
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.total_out = 0;
strm.next_in=(Bytef *)[data bytes];
strm.avail_in = (int)[data length];
// Compresssion Levels:
// Z_NO_COMPRESSION
// Z_BEST_SPEED
// Z_BEST_COMPRESSION
// Z_DEFAULT_COMPRESSION
if (deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY) != Z_OK) return nil;
NSMutableData *compressed = [NSMutableData dataWithLength:16384]; // 16K chunks for expansion
do {
if (strm.total_out >= [compressed length])
[compressed increaseLengthBy: 16384];
strm.next_out = [compressed mutableBytes] + strm.total_out;
strm.avail_out = (uInt)[compressed length] - (uint)strm.total_out;
deflate(&strm, Z_FINISH);
} while (strm.avail_out == 0);
deflateEnd(&strm);
[compressed setLength: strm.total_out];
return [NSData dataWithData:compressed];
}
@end
2、ZIP、RAR、7Z文件解压缩
引用第三方库:
pod 'SSZipArchive'
pod "UnrarKit"
pod 'LzmaSDK-ObjC'
控制器实现
.h 头文件控制器定义:
//
// ZipRarViewController.h
//
// Created by carbonzhao on 2024/5/28.
//
#import "IMBaseClassViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface ZipRarViewController : IMBaseClassViewController
//可为本地路径,亦可为远端路径
@property (nonatomic,strong) NSURL *filePath;
//路径标记,相同标记解压过的不再解压
@property (nonatomic,strong) NSString *fileFlag;
@end
NS_ASSUME_NONNULL_END
.m 文件实现:
//
// ZipRarViewController.m
// QGB_IM2
//
// Created by carbonzhao on 2024/5/28.
//
#import "ZipRarViewController.h"
#import "SSZipArchive.h"
#import "UIBreadView.h"
#import "ZipRar7zUnArchive.h"
NS_ASSUME_NONNULL_BEGIN
@interface UINextTreeView : UIView
{
}
- (void)setDataSource:(NSMutableArray*)list checkActionBlock:(void (^)(NSDictionary *e))checkActionBlock;
@end
NS_ASSUME_NONNULL_END
typedef void (^SubTreeViewCheckedTreeBlock)(NSDictionary *e);
@interface UINextTreeView ()<UITableViewDelegate,UITableViewDataSource>
{
NSMutableArray *dataList;
UITableView *tview;
}
@property (nonatomic,copy) SubTreeViewCheckedTreeBlock ClickTreeBlock;
@end
@implementation UINextTreeView
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
[self setupUI];
}
return self;
}
- (void)setFrame:(CGRect)frame
{
[super setFrame:frame];
if (tview)
{
[tview setFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
}
}
- (void)setupUI
{
dataList = [[NSMutableArray alloc] initWithCapacity:0];
tview = [[UITableView alloc] initWithFrame:self.bounds];
tview.backgroundColor = DSTextPlaceColor;
tview.dataSource = self;
tview.delegate = self;
// tview.tableFooterView = [UIView new];
tview.separatorColor = [UIColor clearColor];
tview.estimatedRowHeight = 0;
tview.estimatedSectionFooterHeight = 0;
tview.estimatedSectionHeaderHeight = 0;
[tview setShowsVerticalScrollIndicator:NO];
[tview setShowsHorizontalScrollIndicator:NO];
// [tview setBackgroundColor:[UIColor redColor]];
// tview.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
// [weakSelf getListAllDing:@"refresh"];
// }];
[self addSubview:tview];
}
#pragma mark - action
- (void)setDataSource:(NSMutableArray*)list checkActionBlock:(void (^)(NSDictionary *e))checkActionBlock
{
[self setClickTreeBlock:checkActionBlock];
[dataList addObjectsFromArray:list];
[tview reloadData];
}
- (void)reloadView
{
dispatch_async(dispatch_get_main_queue(), ^{
[self->tview reloadData];
});
}
- (NSString *)docIcon:(NSString *)ext
{
NSString *ex = [ext lowercaseString];
if ([@[@"xls",@"xlsx"] containsObject:ex])
{
return @"icon_excel_new";
}
else if ([@[@"doc",@"docx"] containsObject:ex])
{
return @"icon_word_new";
}
else if ([@[@"ppt",@"pptx"] containsObject:ex])
{
return @"icon_ppt_new";
}
else if ([@[@"pdf"] containsObject:ex])
{
return @"icon_pdf_new";
}
else if ([@[@"txt"] containsObject:ex])
{
return @"icon_txt_new";
}
else if ([@[@"png",@"jpg",@"jpeg"] containsObject:ex])
{
return @"icon_img_new";
}
else if ([@[@"mov",@"mp4",@"avi",@"mpeg",@"mkv",@"3gp",@"wmv",@"rmvb"] containsObject:ex])
{
return @"icon_mp4_new";
}
else if ([@[@"mp3",@"wav"] containsObject:ex])
{
return @"icon_mp3";
}
else if ([@[@"zip",@"rar",@"7z"] containsObject:ex])
{
return @"icon_zip_new";
}
return @"icon_txt_new";
}
#pragma mark - tableView
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return dataList.count;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat height = 58;
return height;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
CGFloat height = [self tableView:tableView heightForRowAtIndexPath:indexPath];
if (height > 0)
{
CGFloat x = 20;
NSMutableDictionary *e = [dataList objectAtIndex:indexPath.row];
kWeakSelf(self)
NSString *dicon = [e boolForKey:@"isDir"]?@"docshare":[self docIcon:[e stringForKey:@"ext"]];
CGRect rt = CGRectMake(x, (height-30)/2, 30, 30);
UIImageView *dirIcon = [[UIImageView alloc] initWithFrame:rt];
[dirIcon setImage:IMAGE_INIM_NAME(dicon)];
[dirIcon setContentMode:UIViewContentModeScaleAspectFit];
[cell.contentView addSubview:dirIcon];
x += (rt.size.width + 10);
NSString *name = [e stringForKey:@"fileName"];
UIFont *s = Font_size(16);
UIFont *t = Font_size(13);
rt = CGRectMake(x, (height-4-s.lineHeight-t.lineHeight)/2, tableView.frame.size.width-20-x-40, s.lineHeight);
UILabel *label = [[UILabel alloc] initWithFrame:rt];
[label setFont:s];
[label setTextColor:RGBA(10, 10, 10, 1)];
[label setText:name];
[label setTextAlignment:NSTextAlignmentLeft];
[cell.contentView addSubview:label];
NSString *subName = [e stringForKey:@"fileCount"];
rt.origin.y += rt.size.height + 4;
rt.size.width = 140;
label = [[UILabel alloc] initWithFrame:rt];
[label setFont:t];
[label setTextColor:[UIColor colorFromHex:@"#999999"]];
[label setText:subName];
[label setTextAlignment:NSTextAlignmentLeft];
[cell.contentView addSubview:label];
rt.origin.x =+ rt.size.width;
rt.size.width = tableView.frame.size.width-20-rt.origin.x;
rt.size.height = t.lineHeight;
label = [[UILabel alloc] initWithFrame:rt];
[label setFont:t];
[label setTextColor:[UIColor colorFromHex:@"#999999"]];
[label setText:[e stringForKey:@"fileSize"]];
[label setTextAlignment:NSTextAlignmentRight];
[cell.contentView addSubview:label];
// if ([e boolForKey:@"isDir"])
// {
// rt = CGRectMake(tableView.width-34, (height-14)/2, 14, 14);
// UIImageView *iconView = [[UIImageView alloc] initWithFrame:rt];
// [iconView setImage:IMAGE_INIM_NAME(@"icon_arrow")];
// [cell.contentView addSubview:iconView];
// }
rt = CGRectMake(25, height-1, tableView.frame.size.width-25, 1);
UIImageView *iconView = [[UIImageView alloc] initWithFrame:rt];
[iconView setBackgroundColor:RGB(245, 245, 245)];
[cell.contentView addSubview:iconView];
rt = CGRectMake(0, 0, tableView.frame.size.width, height);
iconView = [[UIImageView alloc] initWithFrame:rt];
[iconView setBackgroundColor:RGB(245, 245, 245)];
[cell setSelectedBackgroundView:iconView];
}
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSMutableDictionary *e = [dataList objectAtIndex:indexPath.row];
self.ClickTreeBlock(e);
}
@end
@interface ZipRarViewController ()
@property (nonatomic,strong) UIBreadView *breview;
@end
@implementation ZipRarViewController
- (instancetype)init
{
if (self = [super init])
{
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.breview = [UIBreadView breadViewWithFrame:CGRectMake(0, 0, ScreenWidth, self.safeAreaHeight) viewType:UIBreadViewBreadType];
[self.view addSubview:self.breview];
NSString *fileName = [self.filePath lastPathComponent]; //获取文件名称
[self setTitle:[NSString stringWithFormat:@"%@",fileName]];
if ([self.filePath.absoluteString hasPrefix:@"http"])
{
WeakSelf(self);
[self showToastWithKeepAliveBlock:^(UIToastFenceView *waitView) {
[waitView setViewMode:UIToastFenceViewModeCircle];
[waitView setTitleText:@"下载中..."];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURLRequest *request = [NSURLRequest requestWithURL:self.filePath];
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress *downloadProgress){
CGFloat completedUnitCount = downloadProgress.completedUnitCount*1.0;
CGFloat totalUnitCount = downloadProgress.totalUnitCount*1.0;
CGFloat percent = completedUnitCount/totalUnitCount;
[waitView setProgress:percent];
if (percent == 1.0)
{
[waitView setViewMode:UIToastFenceViewModeText];
[waitView setTitleText:@"下载完成"];
[waitView dismiss:1.5];
}
} destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
NSURL *url = [NSURL fileURLWithPath:userDocuments(@"docPathFile", fileName)];
return url;
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
if (error) {
[waitView setViewMode:UIToastFenceViewModeText];
[waitView setTitleText:@"下载失败"];
[waitView dismiss:1.5];
}
else
{
[waitView dismiss];
NSURL *url = [NSURL fileURLWithPath:userDocuments(@"docPathFile", fileName)];
weakSelf.filePath = url;
[weakSelf toReadySource];
}
}];
[downloadTask resume];
}];
}
else
{
[self toReadySource];
}
}
#pragma mark - 解压文件
- (void)toReadySource
{
NSString *path = [self.filePath path];
NSMutableArray *alist = [NSMutableArray arrayWithArray:[[self.filePath lastPathComponent] componentsSeparatedByString:@"."]];
[alist removeLastObject];
NSString *fileName = [alist componentsJoinedByString:@"."];
NSString *to = userDocuments(@"zipsPathFile", @"");
to = [to stringByAppendingPathComponent:[NSString stringWithFormat:@"%@_%@",self.fileFlag,fileName]];
WeakSelf(self);
// [[NSFileManager defaultManager] removeItemAtPath:to error:nil];
if ([[NSFileManager defaultManager] fileExistsAtPath:to])
{
[self showToastBlock:^(UIToastFenceView *waitView) {
[weakSelf readFiles:to fileName:fileName];
}];
}
else
{
void (^doUnzipBlock)(void) = ^(void)
{
[weakSelf showToastBlock:^(UIToastFenceView *waitView)
{
[waitView setTitleText:@"解压中..."];
BOOL flag = [ZipRar7zUnArchive unarchiveFrom:path toPath:to password:nil];
// BOOL flag = [SSZipArchive unzipFileAtPath:path toDestination:to];
if (flag)
{
[weakSelf readFiles:to fileName:fileName];
}
else
{
[weakSelf showPlaceholderView];
}
}];
};
// if ([ZipRar7zUnArchive isPasswordProtectedAtPath:path])
// {
// NSLog(@"");
// }
// else
// {
// doUnzipBlock();
// }
doUnzipBlock();
}
}
- (void)readFiles:(NSString *)path fileName:(NSString *)fileName
{
NSMutableArray *list = [NSMutableArray arrayWithCapacity:0];
NSFileManager *fm = [NSFileManager defaultManager];
NSError *err = nil;
NSArray *subFilePath = [fm contentsOfDirectoryAtPath:path error:&err];
if (subFilePath)
{
for (NSString * fileName in subFilePath)
{
if (![fileName isEqualToString:@".DS_Store"])
{
NSMutableDictionary *e = [[NSMutableDictionary alloc] initWithCapacity:0];
[e setObject:path forKey:@"path"];
[e setObject:fileName forKey:@"fileName"];
[e setObject:[fileName pathExtension] forKey:@"ext"];
NSString *sub = [path stringByAppendingPathComponent:fileName];
NSMutableDictionary *doj = [NSMutableDictionary dictionaryWithDictionary:[fm attributesOfItemAtPath:sub error:nil]];
BOOL isDir = [[doj fileType] isEqualToString:NSFileTypeDirectory];
[e setObject:boolToStr(isDir) forKey:@"isDir"];
if (isDir)
{
NSArray *rsub = [fm contentsOfDirectoryAtPath:[path stringByAppendingPathComponent:fileName] error:nil];
[e setObject:[NSString stringWithFormat:@"共%@个文件",intToStr(rsub.length)] forKey:@"fileCount"];
NSInteger s = CRMFileSizeByFilePath(sub);
[doj setObject:intToStr(s) forKey:NSFileSize];
}
else
{
[e setObject:@"--" forKey:@"fileCount"];
}
CGFloat f = [doj fileSize] / 1000.0;
NSString *fileSize = nil;
if(f < 1000){
fileSize = [NSString stringWithFormat:@"%.1fKB",f];
}
else if (f < 1000.0 * 1000.0) {
f = round((f/1000.0) * 10) / 10.0;
fileSize = [NSString stringWithFormat:@"%.1fMB",f];
}
else{
f = round((f/1000.0/1000.0) * 10) / 10.0;
fileSize = [NSString stringWithFormat:@"%.1fGB",f];
}
[e setString:fileSize forKey:@"fileSize"];
[list addObject:e];
}
}
WeakSelf(self);
dispatch_sync_on_main_queue(^{
NSBreadData *d = [[NSBreadData alloc] init];
[d setTitle:fileName];
[self.breview addBreadViewTitle:d withConfigBlock:^UIView * _Nullable(NSInteger index, BOOL * _Nonnull useAnimation)
{
UINextTreeView *b = [[UINextTreeView alloc] init];
[b setDataSource:list checkActionBlock:^(NSDictionary *e) {
NSString *p = [e stringForKey:@"path"];
NSString *n = [e stringForKey:@"fileName"];
if ([e boolForKey:@"isDir"])
{
p = [p stringByAppendingPathComponent:n];
[weakSelf readFiles:p fileName:n];
}
else
{
if (weakSelf.delegateBlock)
{
weakSelf.delegateBlock(e);
}
}
}];
return b;
}];
});
}
else
{
[self showPlaceholderView];
}
}
- (void)showPlaceholderView
{
WeakSelf(self);
dispatch_sync_on_main_queue(^{
[weakSelf.breview setHidden:YES];
});
[self showEmptyViewWithTitle:@"加载失败,请尝试刷新页面" icon:IMAGE_INIM_NAME(@"extractFail.png")];
[self ajustEmptyViewWithIconSize:CGSizeMake(ScreenWidth*0.55, (ScreenWidth*0.55)/1.25)];
}
@end
面包屑实现(控制器内部实现切换子页面视图)
.h 头文件源码:
//
// UIBreadView.h
//
// Copyright © 2021 dtx. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSBreadData : NSObject
@property (nonatomic,strong) NSString *title;
@end
typedef NS_ENUM(NSInteger,UIBreadViewType){
UIBreadViewBreadType=0, //面包屑模式,默认
UIBreadViewSearchType, //搜索模式
UIBreadViewHyborType, //混合模式(面包屑搜索均显示)
};
@interface UIBreadView : UIView
//仅有一个面包屑及动画切换的容器
+ (UIBreadView *)breadViewWithFrame:(CGRect)frame viewType:(UIBreadViewType)viewType;
//有一个面包屑及动画切换的容器及可添加的不进行动画切换的容器
+ (UIBreadView *)breadViewWithFrame:(CGRect)frame viewType:(UIBreadViewType)viewType positionFixView:(UIView * (^)(void))positionFixView;
- (void)addBreadViewTitle:(NSBreadData *)data withConfigBlock:(UIView* _Nullable (^)(NSInteger index,BOOL *useAnimation)) setupBlock;
//block返回YES,则隐藏面包屑
- (void)registerSelectActionBlock:(BOOL (^)(NSInteger index))actionBlock;
- (void)registerSearchKeywordBlock:(void (^)(NSString *keyword,BOOL willResign))aBlock;
//搜索UI自定义
- (void)registerConfigurationSearchInterfaceBlock:(void (^)(UIView *pview))aBlock;
- (BOOL)canPopToOneView;
- (CGFloat)breadNavigatorHeight;
- (CGFloat)breadNavigatory;
- (void)setHiddenNavigatorBreadHidden:(BOOL)flag;
- (UIView *)parentView:(UIView *)selfView;
- (UIView *)currentView;
- (void)resignSearchFieldResponder;
- (void)setReturnKeyType:(UIReturnKeyType)type;
//面包屑清除数据回归初始状态
- (void)breadcrumbClearingData;
@end
NS_ASSUME_NONNULL_END
.m 实现文件:
//
// UIBreadView.m
// Copyright © 2021 dtx. All rights reserved.
//
#import "UIBreadView.h"
#import "NSExtentionSloter.h"
#import "SearchBarDisplayCenter.h"
#import "imHeaders.h"
typedef BOOL (^UIBreadViewActionBlock)(NSInteger index);
typedef void (^UIBreadViewSearchKeywordBlock)(NSString *keyword,BOOL willResign);
@interface NSBreadData ()
@property (nonatomic,assign) BOOL isSelected;
@property (nonatomic,assign) CGFloat itemWidth;
//如果有sourceView,则内部处理点击事件切换页面,如果无,将事件反馈到控制器处理
@property (nonatomic,weak) UIView *sourceView;
@end
@implementation NSBreadData
@synthesize title,sourceView,itemWidth,isSelected;
@end
@interface UIBreadView ()<UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout,SearchBarDisplayCenterDelegate>
{
UICollectionView *textView;
UIView *contentView;
NSInteger lastHiglightedRow;
NSMutableArray *dataList;
}
@property (nonatomic,copy) UIBreadViewActionBlock actionBlock;
@property (nonatomic,copy) UIBreadViewSearchKeywordBlock searchBlock;
//是否显示搜索组件进行搜索,如果显示了搜索则不再显示面包屑
@property (nonatomic,assign) UIBreadViewType viewWorkType;
@property (nonatomic,strong) UIView *fixedContainerView;
@property (nonatomic, strong) UIImageView *sepView;
@end
@implementation UIBreadView
@synthesize actionBlock,viewWorkType;
+ (UIBreadView *)breadViewWithFrame:(CGRect)frame viewType:(UIBreadViewType)viewType
{
UIBreadView *view = [[UIBreadView alloc] initWithFrame:frame];
[view setViewWorkType:viewType];
[view setupUI];
return view;
}
+ (UIBreadView *)breadViewWithFrame:(CGRect)frame viewType:(UIBreadViewType)viewType positionFixView:(UIView * (^)(void))positionFixView
{
UIBreadView *view = [[UIBreadView alloc] initWithFrame:frame];
[view setViewWorkType:viewType];
if (positionFixView)
{
UIView *fview = positionFixView();
[view setFixedContainerView:fview];
}
[view setupUI];
return view;
}
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
self->lastHiglightedRow = -1;
self.viewWorkType = UIBreadViewBreadType;
}
return self;
}
- (void)setFrame:(CGRect)frame
{
[super setFrame:frame];
CGRect rt = contentView.frame;
rt.size.height = frame.size.height-rt.origin.y;
[contentView setFrame:rt];
for (UIView *aview in contentView.subviews)
{
[aview setFrame:CGRectMake(0, 0, frame.size.width, rt.size.height)];
}
}
- (void)setupUI{
dataList = [[NSMutableArray alloc] initWithCapacity:0];
CGRect rt = CGRectMake(20, 0, self.bounds.size.width-40, 44);
UICollectionViewFlowLayout *flowLayout=[[UICollectionViewFlowLayout alloc] init];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
textView = [[UICollectionView alloc] initWithFrame:rt collectionViewLayout:flowLayout];
// textView.backgroundColor = [UIColor yellowColor];
[textView setDelegate:self];
[textView setDataSource:self];
// [textView setPagingEnabled:YES];
[textView setBackgroundColor:[UIColor clearColor]];
[textView setShowsHorizontalScrollIndicator:NO];
[textView setShowsVerticalScrollIndicator:NO];
[textView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"dequeueIdentifier"];
[self addSubview:textView];
CGFloat y = rt.origin.y+rt.size.height;
if (self.viewWorkType == UIBreadViewSearchType)
{
[textView setHidden:YES];
CGRect rt = CGRectMake(0, 0, ScreenWidth, 50);
UIView *header = [[UIView alloc]initWithFrame:rt];
header.backgroundColor = [UIColor whiteColor];
[header setTag:404];
[self addSubview:header];
SearchBarDisplayCenter *searchBar = [[SearchBarDisplayCenter alloc]initWithFrame:CGRectMake(0, 3, ScreenWidth, 47)];
searchBar.userInteractionEnabled = YES;
searchBar.placeholderStr = @"搜索";
[searchBar breadChangeFrameAndSearchIcon];
// searchBar.seachIconIV.image = [UIImage imageInImBundle:@"bread_search"];
//
// [searchBar.seachIconIV mas_updateConstraints:^(MASConstraintMaker *make) {
//
// make.width.mas_equalTo(17);
// make.height.mas_equalTo(17);
// }];
//
// searchBar.placeholderColor = colorFromText(@"#999999");
[searchBar setTag:405];
searchBar.backgroundColor = [UIColor whiteColor];
[searchBar setDelegate:self];
[header addSubview:searchBar];
y = rt.origin.y+rt.size.height;
}
else if (self.viewWorkType == UIBreadViewHyborType)
{
rt = CGRectMake(0, 0, ScreenWidth, 50);
UIView *header = [[UIView alloc]initWithFrame:rt];
header.backgroundColor = [UIColor whiteColor];
[header setTag:404];
[self addSubview:header];
SearchBarDisplayCenter *searchBar = [[SearchBarDisplayCenter alloc]initWithFrame:CGRectMake(0, 3, ScreenWidth, 47)];
[searchBar setTag:405];
searchBar.userInteractionEnabled = YES;
searchBar.placeholderStr = @"搜索";
[searchBar breadChangeFrameAndSearchIcon];
[searchBar setDelegate:self];
[header addSubview:searchBar];
y = rt.origin.y+rt.size.height;
rt = textView.frame;
rt.origin.y = y;
[textView setFrame:rt];
y = rt.origin.y+rt.size.height;
}
[textView setDataObject:NSStringFromCGRect(textView.frame)];
rt = CGRectMake(0, y, self.bounds.size.width, 10);
UIImageView *sepView = [[UIImageView alloc] initWithFrame:rt];
self.sepView = sepView;
[sepView setBackgroundColor:DSTextPlaceColor];
[self addSubview:sepView];
y = rt.origin.y+rt.size.height;
if (self.fixedContainerView)
{
rt = self.fixedContainerView.frame;
rt.origin.y = y;
[self.fixedContainerView setFrame:rt];
[self addSubview:self.fixedContainerView];
y = rt.origin.y+rt.size.height;
}
rt = CGRectMake(0, y, self.bounds.size.width, self.bounds.size.height- (rt.origin.y+rt.size.height));
contentView = [[UIView alloc] initWithFrame:rt];
[contentView setBackgroundColor:[UIColor whiteColor]];
[contentView setTag:90001];
[self addSubview:contentView];
}
- (void)addBreadViewTitle:(NSBreadData *)data withConfigBlock:(UIView* _Nullable (^)(NSInteger index,BOOL *useAnimation)) setupBlock
{
WeakSelf(self);
__weak typeof(dataList) thisDataList = dataList;
__weak typeof(textView) thisTextView = textView;
__weak typeof(contentView) thisContentView = contentView;
[textView performBatchUpdates:^{
CGFloat w = [data.title stringSizeWithFont:[UIFont systemFontOfSize:14]].width;
if (thisDataList.count > 0)
{
w += 28;
}
data.itemWidth = w;
[data setIsSelected:NO];
[thisDataList addObject:data];
[thisTextView insertItemsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:thisDataList.count-1 inSection:0]]];
if (thisDataList.count > 1)
{
NSBreadData *e = [thisDataList objectAtIndex:thisDataList.count-2];
[e setIsSelected:YES];
self->lastHiglightedRow = thisDataList.count-3;
if (self->lastHiglightedRow > -1)
{
// e = [dataList objectAtIndex:lastHiglightedRow];
// [e setIsSelected:NO];
//
// [textView reloadItemsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:lastHiglightedRow inSection:0]]];
}
[thisTextView reloadItemsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:thisDataList.count-2 inSection:0]]];
}
} completion:^(BOOL finished) {
}];
if (setupBlock)
{
NSInteger count = contentView.subviews.count;
// for (NSInteger idx=0;idx<contentView.subviews.count;idx++)
// {
// UIView *view = [contentView.subviews objectAtIndex:idx];
// CGRect rt = view.frame;
// rt.origin.x = - (count-idx)*self.bounds.size.width;
// [view setFrame:rt];
// }
BOOL useAnimation = YES;
UIView *view = setupBlock(count,&useAnimation);
__weak typeof(view) thisView = view;
data.sourceView = view;
if (view)
{
CGRect rt = view.frame;
rt.origin.x = thisContentView.subviews.count>0?weakSelf.bounds.size.width:0;
rt.size = thisContentView.frame.size;
[view setFrame:rt];
[thisContentView addSubview:thisView];
if (thisContentView.subviews.count>0)
{
if (useAnimation)
{
[UIView animateWithDuration:0.3 animations:^
{
CGRect rt = thisView.frame;
rt.origin.x = 0;
[thisView setFrame:rt];
}
completion:^(BOOL finished)
{
}];
}
else
{
CGRect rt = thisView.frame;
rt.origin.x = 0;
[thisView setFrame:rt];
}
}
}
}
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self->dataList.count-1 inSection:0];
[self->textView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionRight animated:YES];
};
- (void)setReturnKeyType:(UIReturnKeyType)type
{
SearchBarDisplayCenter *searchBar = [[self viewWithTag:404] viewWithTag:405];
searchBar.searchField.returnKeyType = type;
}
- (UIView *)parentView:(UIView *)selfView
{
NSInteger index = [contentView.subviews indexOfObject:selfView];
if (index > 0)
{
return [contentView.subviews objectAtIndex:index-1];
}
return nil;
}
- (UIView *)currentView
{
return [contentView.subviews lastObject];
}
- (void)registerSelectActionBlock:(BOOL (^)(NSInteger index))actionBlock
{
[self setActionBlock:actionBlock];
}
- (void)registerSearchKeywordBlock:(void (^)(NSString *keyword,BOOL willResign))aBlock
{
[self setSearchBlock:aBlock];
}
- (void)registerConfigurationSearchInterfaceBlock:(void (^)(UIView *pview))aBlock
{
SearchBarDisplayCenter *searchBar = [[self viewWithTag:404] viewWithTag:405];
CGRect ft = searchBar.frame;
UIView *aview = [[UIView alloc] initWithFrame:ft];
[aview setUserInteractionEnabled:YES];
[[self viewWithTag:404] addSubview:aview];
aBlock(aview);
}
- (CGSize)itemSizeWithIndex:(NSIndexPath *)indexPath{
NSBreadData *data = [dataList objectAtIndex:indexPath.row];
CGFloat w = data.itemWidth;
return CGSizeMake(w+5, textView.frame.size.height);
}
- (void)setHiddenNavigatorBreadHidden:(BOOL)flag
{
if (textView.isHidden != flag)
{
[textView setHidden:flag];
if (flag)
{
[UIView animateWithDuration:0.3 animations:^
{
CGRect rt = self->textView.frame;
rt.origin.y = -rt.size.height;
[self->textView setFrame:rt];
CGFloat y = 0;
if ([self viewWithTag:404])
{
y = [self viewWithTag:404].frame.origin.y+[self viewWithTag:404].frame.size.height;
}
rt = CGRectMake(0, y, self.bounds.size.width, 5);
[self.sepView setFrame:rt];
y += 5;
rt = CGRectMake(0, y, self.bounds.size.width, self.bounds.size.height-y);
[self->contentView setFrame:rt];
}
completion:^(BOOL finished)
{
CGRect rt = self->textView.frame;
rt.origin.x = self.bounds.size.width;
rt.origin.y = 0;
[self->textView setFrame:rt];
}];
}
else
{
[UIView animateWithDuration:0.3 animations:^
{
CGRect rt = self->textView.frame;
rt.origin.x = 20;
rt.origin.y = CGRectFromString((NSString *)[self->textView dataObject]).origin.y;
[self->textView setFrame:rt];
CGFloat y = rt.origin.y+rt.size.height;
rt = CGRectMake(0, y, self.bounds.size.width, 5);
[self.sepView setFrame:rt];
y += 5;
rt = CGRectMake(0, y, self.bounds.size.width, self.bounds.size.height-y);
[self->contentView setFrame:rt];
}
completion:^(BOOL finished)
{
}];
}
}
for (UIView *aview in contentView.subviews)
{
[aview setFrame:CGRectMake(0, 0, contentView.size.width, contentView.size.height)];
}
}
- (BOOL)canPopToOneView
{
BOOL flag = NO;
if (dataList.count==0) {
return flag;
}
NSBreadData *mObject = [dataList lastObject];
if (mObject.sourceView && dataList.count>1)
{
flag = YES;
[self poptoOneViewWithAnimation:dataList.count-2];
}
return flag;
}
- (CGFloat)breadNavigatorHeight
{
if (self.viewWorkType == UIBreadViewSearchType)
{
return MAX(textView.frame.size.height, [self viewWithTag:404].frame.size.height);
}
else if (self.viewWorkType == UIBreadViewHyborType)
{
return textView.frame.size.height+[self viewWithTag:404].frame.size.height;
}
else
{
return textView.frame.size.height;
}
}
- (CGFloat)breadNavigatory
{
return [self viewWithTag:404].frame.origin.y+[self viewWithTag:404].frame.size.height;
}
- (void)resignSearchFieldResponder
{
SearchBarDisplayCenter *searchBar = [[self viewWithTag:404] viewWithTag:405];
[searchBar restoreInitialState];
[searchBar.searchField resignFirstResponder];
[self poptoOneViewWithAnimation:1];
}
- (void)poptoOneViewWithAnimation:(NSInteger)row
{
if (self.actionBlock)
{
BOOL flag = self.actionBlock(row);
[self setHiddenNavigatorBreadHidden:flag];
}
NSBreadData *mObject = [dataList objectAtIndex:row];
if (mObject.sourceView)
{
for (NSInteger ix=dataList.count-1; ix>row;ix--)
{
NSBreadData *mObject = [dataList objectAtIndex:ix];
UIView *aview = mObject.sourceView;
[UIView animateWithDuration:0.3 animations:^
{
CGRect rt = aview.frame;
rt.origin.x = self.bounds.size.width;
[aview setFrame:rt];
}
completion:^(BOOL finished)
{
[aview removeFromSuperview];
}];
}
[dataList removeObjectsInRange:NSMakeRange(row+1, dataList.count- (row+1))];
NSBreadData *m = [dataList lastObject];
[m setIsSelected:NO];
if (dataList.count > 1)
{
m = [dataList objectAtIndex:dataList.count-2];
[m setIsSelected:YES];
}
if (textView)
{
[textView reloadSections:[NSIndexSet indexSetWithIndex:0]];
}
}
}
- (void)breadcrumbClearingData {
if (self.actionBlock)
{
BOOL flag = self.actionBlock(0);
[self setHiddenNavigatorBreadHidden:flag];
}
if (dataList.count > 0) {
// for (NSInteger ix=0; ix>dataList.count;ix++)
// {
// NSBreadData *mObject = [dataList objectAtIndex:ix];
// UIView *aview = mObject.sourceView;
// [aview removeFromSuperview];
// }
[dataList removeAllObjects];
}
if (textView)
{
[textView reloadSections:[NSIndexSet indexSetWithIndex:0]];
}
}
#pragma mark - SearchBarDisplayCenterDelegate
- (void)getSearchKeyWordWhenChanged:(NSString *)searchWord
{
if (self.searchBlock)
{
self.searchBlock(searchWord,NO);
}
}
- (void)textFieldBecomeResponder:(NSString*)text
{
if (self.searchBlock)
{
self.searchBlock(text,NO);
}
}
- (void)textFieldResignResponder:(NSString*)text
{
if (self.searchBlock)
{
self.searchBlock(text,YES);
}
}
#pragma mark - UICollectionView
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
NSInteger count = dataList.count;
return count;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
return 0;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
{
return 0;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return [self itemSizeWithIndex:indexPath];
}
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"dequeueIdentifier" forIndexPath:indexPath];
[cell.contentView setBackgroundColor:[UIColor clearColor]];
CGSize size = [self itemSizeWithIndex:indexPath];
NSBreadData *mObject = [dataList objectAtIndex:indexPath.row];
CGFloat x = 5;
if (indexPath.row>0)
{
CGRect rt = CGRectMake(x, (size.height-10)/2, 10, 10);
UIImageView *iconView = [cell.contentView viewWithTag:90];
if (!iconView)
{
iconView = [[UIImageView alloc] initWithFrame:rt];
[iconView setImage:IMAGE_INIM_NAME(@"bookList_xiayiye")];
[iconView setTag:90];
[cell.contentView addSubview:iconView];
}
if (mObject.isSelected)
{
[iconView setTintColor:RGB(0, 125, 255)];
}
x += rt.size.width;
}
[[cell.contentView viewWithTag:90] setHidden:indexPath.row == 0];
CGRect rt = CGRectMake(x, 0, size.width-x, size.height);
UIButton *button = [cell.contentView viewWithTag:91];
if (!button)
{
button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setTag:91];
[button.titleLabel setFont:[UIFont systemFontOfSize:14]];
[button setTitleColor:RGB(40, 40, 40) forState:UIControlStateNormal];
[button setTitleColor:RGB(0, 125, 255) forState:UIControlStateSelected];
[cell.contentView addSubview:button];
}
[button setUserInteractionEnabled:NO];
[button setFrame:rt];
[button setTitle:mObject.title forState:UIControlStateNormal];
[button setDataObject:mObject];
[button setSelected:mObject.isSelected];
[cell setBackgroundColor:[UIColor clearColor]];
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
// UICollectionViewCell *cell = [contentView cellForItemAtIndexPath:indexPath];
[self poptoOneViewWithAnimation:indexPath.row];
}
@end
使用
ZipRarViewController *c = [[ZipRarViewController alloc] init];
//传入压缩包路径,支持本地文件及远程文件URL
[c setFilePath:url];
//文中路径进行MD5,目的是区分记录解压记录,已解压过的后期不再解压而是直接读取展示
[c setFileFlag:[fileFlag md5Byte32Lower]];
[c setDelegateBlock:^(NSDictionary *data) {
NSString *p = [data stringForKey:@"path"];
NSString *f = [data stringForKey:@"fileName"];
weakSelf.fileURL = [NSURL fileURLWithPath:[p
stringByAppendingPathComponent:f]];
[weakSelf openDocument:weakSelf.fileURL];
}];
[self.navigationController pushViewController:c animated:YES];
//打开文件方法
- (void)openDocument:(NSURL *)url {
if ([QLPreviewController canPreviewItem:url]) {
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf initKkpreview];
});
}
}
- (void)initKkpreview {
self.kkpreview = [[QLPreviewController alloc] init];
self.kkpreview.delegate = self;
self.kkpreview.dataSource = self;
WeakSelf(self);
UIView *rview = [UINaviButton naviButtonWithActionBlock:^{
[weakSelf.kkpreview.navigationController popViewControllerAnimated:YES];
}];
UIBarButtonItem *item = [[UIBarButtonItem alloc]initWithCustomView:rview];
self.kkpreview.navigationItem.leftBarButtonItem = item;
[self.navigationController pushViewController:self.kkpreview animated:YES];
}
#pragma mark - QLPreviewControllerDataSource
- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller{
return 1;
}
- (id<QLPreviewItem>)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index{
return self.fileURL;
}