OC IOS 文件解压缩预览

news2024/11/17 11:02:42

热很。。热很。。。。夏天的城市只有热浪没有情怀。。。

来吧,come on。。。

 引用第三方库:

pod 'SSZipArchive'

开发实现:

一、控制器实现

头文件控制器定义:

//
//  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

实现文件定义:

//
//  ZipRarViewController.m
//
//  Created by carbonzhao on 2024/5/28.
//

#import "ZipRarViewController.h"
#import "SSZipArchive.h"
#import "UIBreadView.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 ([@[@"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"] containsObject:ex])
    {
        return @"icon_zip_new";
    }
    return @"";
}

#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"]?@"icon_folder_icon":[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)];
        [cell.contentView addSubview:dirIcon];
        
        x += (rt.size.width + 10);
        NSString *name = [e stringForKey:@"fileName"];
        rt = CGRectMake(x, 0, tableView.frame.size.width-20-x-40, height);
        UILabel *label = [[UILabel alloc] initWithFrame:rt];
        [label setFont:Font_size(16)];
        [label setTextColor:RGBA(10, 10, 10, 1)];
        [label setText:name];
        [label setTextAlignment:NSTextAlignmentLeft];
        [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];
    NSString *fileName = [[[self.filePath lastPathComponent] componentsSeparatedByString:@"."] firstObject];
    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 stringByAppendingPathComponent:fileName] fileName:fileName];
        }];
    }
    else
    {
        [self showToastBlock:^(UIToastFenceView *waitView)
        {
            [waitView setTitleText:@"解压中..."];
            BOOL flag = [SSZipArchive unzipFileAtPath:path toDestination:to];
            if (flag)
            {
                [weakSelf readFiles:[to stringByAppendingPathComponent:fileName] fileName:fileName];
            }
            else
            {
                [waitView setTitleText:@"解压失败"];
                [waitView waitForSeconds];
            }
        }];
    }
}


- (void)readFiles:(NSString *)path fileName:(NSString *)fileName
{
    NSMutableArray *list = [NSMutableArray arrayWithCapacity:0];
    NSFileManager *fm = [NSFileManager defaultManager];
    NSArray *subFilePath = [fm contentsOfDirectoryAtPath:path error:nil];
    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"];
            BOOL isDir = NO;
            [fm fileExistsAtPath:[path stringByAppendingPathComponent:fileName] isDirectory: &isDir];
            [e setObject:boolToStr(isDir) forKey:@"isDir"];
            [e setObject:[fileName pathExtension] forKey:@"ext"];
            [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;
        }];
    });
}
@end

二、面包屑实现(控制器内部实现切换子页面视图)

头文件源码:

//
//  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

实现文件:

//
//  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;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1706859.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

solidworks 3D草图案例2-方块异形切

单位mm 单位mm 长方体 底面是48mm*48mm&#xff0c;高为60mm 3D草图 点击线&#xff0c;根据三视图&#xff0c;绘制角度线&#xff0c; 由于三点确定一个面&#xff0c;因此确定三点就可以了 基准面 点击参考几何体-基准面&#xff0c;依次点击3个点 曲面切除 完成后点击插…

02--大数据Hadoop集群实战

前言&#xff1a; 前面整理了hadoop概念内容&#xff0c;写了一些概念和本地部署和伪分布式两种&#xff0c;比较偏向概念或实验&#xff0c;今天来整理一下在项目中实际使用的一些知识点。 1、基础概念 1.1、完全分布式 Hadoop是一个开源的分布式存储和计算框架&#xff0…

Serverless应用引擎SAE评测|一分钟部署在线游戏

Serverless应用引擎SAE评测|一分钟部署在线游戏 什么是Serverless应用引擎SAE一分钟部署在线游戏SAE控制台 资源释放其他操作 在进行Serverless应用引擎SAE评测之前&#xff0c;首先需要了解一下什么是SAE。 什么是Serverless应用引擎SAE Serverless应用引擎SAE&#xff08;Se…

超频是什么意思?超频的好处和坏处

你是否曾经听说过超频&#xff1f;在电脑爱好者的圈子里&#xff0c;这个词似乎非常熟悉&#xff0c;但对很多普通用户来说&#xff0c;它可能还是一个神秘而陌生的存在。 电脑超频是什么意思 电脑超频&#xff08;Overclocking&#xff09;&#xff0c;顾名思义&#xff0c;是…

C++面向对象程序设计 - 标准输出流

在C中&#xff0c;标准输出流通常指的是与标准输出设备&#xff08;通常是终端或控制台&#xff09;相关联的流对象。这个流对象在C标准库中被定义为std::cout、std::err、std::clog&#xff0c;它们是std::ostream类的一个实例。 一、cout&#xff0c;cerr和clog流 ostream类…

VLDB ’25 最后 6 天截稿,58 个顶会信息纵览;ISPRS 城市分割数据集上线

「顶会」板块上线 hyper.ai 官网啦&#xff01;该板块为大家提供最新最全的 CCF A 类计算机顶会信息&#xff0c;包含会议简介、截稿倒计时、投稿链接等。 你是不是已经注册了顶会&#xff0c;但对截稿时间较为模糊&#xff0c;老是在临近 ddl 时才匆忙提交&#xff1b;又或者…

监控云安全的9个方法和措施

如今&#xff0c;很多企业致力于提高云计算安全指标的可见性&#xff0c;这是由于云计算的安全性与本地部署的安全性根本不同&#xff0c;并且随着企业将应用程序、服务和数据移动到新环境&#xff0c;需要不同的实践。检测云的云检测就显得极其重要。 如今&#xff0c;很多企业…

模拟量4~20mA电流传感器接线方式

一、模拟量4~20mA电流传感器接线方式 无源双线制是常见的电流型传感器接线方式&#xff0c;它具有简单、经济的特点。其接线方式如下&#xff1a; 传感器的“”接到数据采集器的电源“”上&#xff0c; 传感器的“-”端子连接到数据采集器的“AI”端子上&#xff0c; 数据采集器…

翻译《The Old New Thing》- What did MakeProcInstance do?

What did MakeProcInstance do? - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20080207-00/?p23533 Raymond Chen 2008年02月07日 MakeProcInstance 做了什么&#xff1f; MakeProcInstance 宏实际上什么也不做。 #define MakeProcInst…

HackTheBox-Machines--Beep

Beep测试过程 1 信息收集 nmap端口扫描 gryphonwsdl ~ % nmap -sC -sV 10.129.137.179 Starting Nmap 7.94 ( https://nmap.org ) at 2024-05-28 14:39 CST Nmap scan report for 10.129.229.183 Host is up (0.28s latency). Not shown: 988 closed tcp ports (conn-refused…

python办公自动化——(二)替换PPT文档中图形数据-柱图

效果: 数据替换前 : 替换数据后: 实现代码 import collections.abc from pptx import Presentation from pptx.util import Cm,Pt import pyodbc import pandas as pd from pptx.chart.data import CategoryChartData…

C语言 数组—— 一维数组下标越界问题分析

目录 数组元素的访问 一维数组元素的越界访问 二维数组元素的越界访问 小结 数组元素的访问 访问数组元素时&#xff0c; 下标越界 是大忌&#xff01;  编译器通常不检查下标越界&#xff0c;导致程序运行时错误  下标越界&#xff0c;将访问数组以外的空间  …

如何学到数据库从入门到入土(MySQL篇)

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人能接…

开源AI模型:未来发展的领航者!

开源AI模型简单概述 开源AI模型是指那些其源代码可以自由使用、修改和分发的人工智能模型。这些模型通常由社区成员共同开发&#xff0c;并且可以在遵守相应许可证的前提下被任何人用于商业或研究目的。开源AI模型的出现极大地推动了人工智能技术的发展&#xff0c;使得更多的…

uniapp - 文章模块页面

在上一篇文章中&#xff0c;创建了一个空白的文章模块页面。在这一篇文章&#xff0c;让我们来向页面中填充内容。 目录 页面效果涉及uniapp组件1.view2.swiper3.scroll-view4.属性解读1) class"style1 style2 .."2) circular单属性无赋值3) :autoplay"autoplay…

gitlab将本地文件项目上传至gitlab服务

打开gitlab网页界面&#xff0c;登陆管理员账号 &#xff08;测试服务器安装的gitlab&#xff0c;浏览器输入ip或配置的gitlab地址&#xff09; 创建新项目 使用gitlab创建项目 创建一个新项目&#xff08;忽略分组&#xff09; &#xff08;忽略分组&#xff09; 在创建工…

网络原理-------TCP协议

文章目录 TCP协议TCP协议段格式TCP原理确认应答机制 (安全机制)超时重传机制 (安全机制)连接管理机制 (安全机制)滑动窗口 (效率机制)流量控制 (安全机制)拥塞控制 (安全机制)延迟应答 (效率机制)捎带应答 (效率机制) 基于TCP的应用层协议 TCP协议 TCP, 即 Transmission Contr…

鸿蒙OS开发:【一次开发,多端部署】(导航栏) 导航栏

一多导航栏 介绍 本示例展示了导航组件在不同设备形态下的样式。 在sm设备上&#xff0c;以tabs形式展示&#xff0c;内容、导航为上下样式布局&#xff0c;通过点击底部tabs切换内容&#xff1b;在md/lg设备上&#xff0c;以[SideBarContainer]形式展示&#xff0c;内容、导…

OZON平台支持什么ERP,芒果店长ERP

随着跨境电商行业的飞速发展&#xff0c;越来越多的电商平台与ERP系统展开了紧密的合作&#xff0c;旨在通过技术整合提升商家的运营效率和市场竞争力。在众多电商平台中&#xff0c;OZON以其独特的商业模式和强大的市场影响力&#xff0c;吸引了众多商家的目光。而芒果店长ERP…

Linux基础知识,配置网卡(七)

一、简介 1. 虚拟机的网络设置 目的1&#xff1a;让物理机和虚拟机之间可以互相通信 目的2&#xff1a;让虚拟机可以上网 目的3&#xff1a;让虚拟机之间可以互相通信 2.网络的类别 类别1&#xff1a;实现物理机和虚拟机之间通信 物理机只要安装了vmware之后&#xff0c;就会…