项目实战No4 清除缓存

来源:互联网 发布:课程表软件哪个好 编辑:程序博客网 时间:2024/05/16 13:07

一 cell设置

  • cell数据
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    XMGMeCell *cell = [tableView dequeueReusableCellWithIdentifier:XMGMeCellId];    if (indexPath.section == 0) {        cell.textLabel.text = @"登录/注册";        cell.imageView.image = [UIImage imageNamed:@"setup-head-default"];    } else {        cell.textLabel.text = @"离线下载";    }    return cell;}
  • 每组的间距调整
  self.tableView.sectionHeaderHeight = 0;  self.tableView.sectionFooterHeight = 10;
  • cell距离页面头部间隙过大,重写setFrame
    • 通过frame.origin.y -= 25实现cell上移,但是整体不会上移,不建议这么做
    • 通过设置内边距:
// 设置内边距(-25代表:所有内容往上移动25)    self.tableView.contentInset = UIEdgeInsetsMake(-25, 0, 0, 0);
  • 自定义cell初始化,cell创建时调用一次
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {        self.accessoryType = UITableViewCellAccessoryDisclosureIndicator;        self.textLabel.textColor = [UIColor darkGrayColor];        // 设置背景图片        self.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"mainCellBackground"]];    }    return self;}
  • 图片拉伸设置
    这里写图片描述

  • 调整image和label间距

    • 问题:下面label也会跟着调整,需要增加判断
- (void)layoutSubviews{    [super layoutSubviews];    if (self.imageView.image == nil) return;    // 调整imageView    self.imageView.y = XMGCommonMargin * 0.5;    self.imageView.height = self.contentView.height - 2 * self.imageView.y;    self.imageView.width = self.imageView.height;    // 调整Label    self.textLabel.x = CGRectGetMaxX(self.imageView.frame) + XMGCommonMargin;    //  self.textLabel.x = self.imageView.x + self.imageView.width + XMGCommonMargin;   // 另一种写法 :    //   CGRectGetMaxX(self.imageView.frame) == self.imageView.x + self.imageView.width    //   CGRectGetMinX(self.imageView.frame) == self.imageView.x    //   CGRectGetMidX(self.imageView.frame) == self.imageView.x + self.imageView.width * 0.5    //   CGRectGetMidX(self.imageView.frame) == self.imageView.centerX}

二 加载方块数据

  • 自定义Footer,重写initWithFrame
- (instancetype)initWithFrame:(CGRect)frame{    if (self = [super initWithFrame:frame]) {        // 请求参数        NSMutableDictionary *params = [NSMutableDictionary dictionary];        params[@"a"] = @"square";        params[@"c"] = @"topic";        // 发送请求        XMGWeakSelf;    [[AFHTTPSessionManager manager] GET:RequestURL parameters:params success:^(NSURLSessionDataTask *task, id responseObject) {    [weakSelf createSquares:[NBSquare objectArrayWithKeyValuesArray:responseObject[@"square_list"]]];     } failure:^(NSURLSessionDataTask *task, NSError *error) {        }];    }    return self;}
  • 需要3个属性,建一个modal
@interface NBSquare : NSObject/** 名字 */@property (nonatomic, copy) NSString *name;/** 图标 */@property (nonatomic, copy) NSString *icon;/** 链接 */@property (nonatomic, copy) NSString *url;@end
  • 九宫格方块实现
/** * 创建方块 */- (void)createSquares:(NSArray *)squares{    // 每行的列数    int colsCount = 4;    // 按钮尺寸    CGFloat buttonW = self.width / colsCount;    CGFloat buttonH = buttonW;    // 遍历所有的模型    NSUInteger count = squares.count;    for (NSUInteger i = 0; i < count; i++) {        // 创建按钮        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];        [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];        [self addSubview:button];        // frame        CGFloat buttonX = (i % colsCount) * buttonW;        CGFloat buttonY = (i / colsCount) * buttonH;        button.frame = CGRectMake(buttonX, buttonY, buttonW, buttonH);   }}
  • 设置数据
// 设置题目[button setTitle:square.name forState:UIControlStateNormal];

注意:设置图片,不只拿到image就行,需要用set…forState记录状态;

  • 下载图片方法1:
[[SDWebImageManager sharedManager] downloadImageWithURL:[NSURL URLWithString:square.icon] options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {    [button setImage:image forState:UIControlStateNormal];}];
  • 下载图片方法2:
[button sd_setImageWithURL:[NSURL URLWithString:square.icon] forState:UIControlStateNormal];
  • 子控件button重新布局
- (instancetype)initWithFrame:(CGRect)frame{    if (self = [super initWithFrame:frame]) {        self.titleLabel.textAlignment = NSTextAlignmentCenter;        self.titleLabel.font = [UIFont systemFontOfSize:14];        [self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];        [self setBackgroundImage:[UIImage imageNamed:@"mainCellBackground"] forState:UIControlStateNormal];    }    return self;}- (void)layoutSubviews{    [super layoutSubviews];    self.imageView.width = self.width * 0.5;    self.imageView.height = self.imageView.width;    self.imageView.y = self.height * 0.1;    self.imageView.centerX = self.width * 0.5;    self.titleLabel.width = self.width;    self.titleLabel.y = CGRectGetMaxY(self.imageView.frame);    self.titleLabel.x = 0;    self.titleLabel.height = self.height - self.titleLabel.y;}
  • 一个控件不能响应点击事件,原因可能有:
    • 1> userInteractionEnabled = NO;
    • 2> enabled = NO;
    • 3> 父控件的userInteractionEnabled = NO;
    • 4> 父控件的enabled = NO;
    • 5> 控件已经超出父控件的边框范围

项目中由于没有设置父控件高度,所以点击没反应。

三 父控件footer加高度

  • 计算父控件高度方法1:根据有多少列,计算高度
    • 如果行数能被子控件数量整除,列数 = 总数 / 行数;
    • 如果行数不能被子控件数量整除,列数 = 总数 / 行数 + 1;
  // 设置footer的高度    NSUInteger rowsCount = count / colsCount;    if (count % colsCount) { // 不能整除,行数+1        rowsCount++;    }

合成公式写法如下:总页数 == (总个数 + 每页的个数 - 1) / 每页的个数

   NSUInteger rowsCount = (count + colsCount - 1) / colsCount;   self.height = rowsCount * buttonH;
  • 方法2:拿到按钮的最高高度
self.height = CGRectGetMaxY(button.frame);

注意点:设置FooterView与设置height前后顺序不一样,效果不一样,期望是先设置height,在设置footerView

  • 解决方法1:重新设置footerView
    // 重新设置footerView    UITableView *tableView = (UITableView *)self.superview;    tableView.tableFooterView = self;
  • 解决方法2:直接改contentSize
   UITableView *tableView = (UITableView *)self.superview;   tableView.contentSize = CGSizeMake(0, CGRectGetMaxY(self.frame));
  • button间加分割线
    • 方法1: 添加很多高宽为1的view
    • 方法2: 设置按钮宽度/高度减1,位置不变
    • 方法3: 美工提供一个带边框的图片
 [self setBackgroundImage:[UIImage imageNamed:@"mainCellBackground"] forState:UIControlStateNormal];

四 点击按钮push

  • 哪个按钮被点击
    • 加1数组计算按钮位置
      // 计算被点击按钮在子控件数组的位置
      NSUInteger index = [self.subviews indexOfObject:button];
      XMGSquare *square = self.squares[index];
    • 绑定tag
XMGSquare *square = squares[i];button.tag = i;XMGSquare *square = self.squares[button.tag];
  • 替换上述方法:封装button,一个button对应一个模型
- (void)setSquare:(XMGSquare *)square{    _square = square;    // 数据    [self setTitle:square.name forState:UIControlStateNormal];    // 设置按钮的image    [self sd_setImageWithURL:[NSURL URLWithString:square.icon] forState:UIControlStateNormal];}
  • 点击按钮跳转webView
    • 判断按钮点击url地址以“http”开头
- (void)buttonClick:(XMGSquareButton *)button{    if ([button.square.url hasPrefix:@"http"]) {        XMGWebViewController *webVc = [[XMGWebViewController alloc] init];        // 取出当前选中的导航控制器        UITabBarController *rootVc = (UITabBarController *)self.window.rootViewController;        UINavigationController *nav = (UINavigationController *)rootVc.selectedViewController;        [nav pushViewController:webVc animated:YES];  //  不关心控制器的位置,位置会变化          //   [UIApplication sharedApplication].keyWindow;    //   [[rootVc.childViewControllers lastObject] pushViewController:webVc animated:YES];//        XMGLog(@"%@", rootVc.selectedViewController);    }}

五 网页显示

  • 遵守UIWebView代理
@interface WebViewController () <UIWebViewDelegate> @end- (void)viewDidLoad {    [super viewDidLoad];    self.title = self.square.name;    [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.square.url]]];    self.webView.backgroundColor = XMGCommonBgColor;    // 设置偏移量    self.webView.scrollView.contentInset = UIEdgeInsetsMake(64, 0, 0, 0);}
  • 前进后退箭头交互可否点击
#pragma mark - <UIWebViewDelegate>- (void)webViewDidFinishLoad:(UIWebView *)webView{    self.backItem.enabled = webView.canGoBack;    self.forwardItem.enabled = webView.canGoForward;}

六 清除缓存

- (void)viewDidLoad {    [super viewDidLoad];    self.navigationItem.title = @"设置";    self.view.backgroundColor = XMGCommonBgColor;    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:XMGSettingCellId];    // 设置内边距(-25代表:所有内容往上移动25)    self.tableView.contentInset = UIEdgeInsetsMake(XMGCommonMargin - 35, 0, 0, 0);    XMGLog(@"%f", @"/Users/yonghuming/Desktop/课堂共享/顶部的cell.mp4".fileSize / 1000.0 / 1000.0);// 手机上的磁盘缓存 == 从网络上下载的数据 + 写入的数据// 手机上的磁盘缓存的数据类型 == 图片 + 多媒体文件}
  • 获取文件夹的大小,文件夹没有直接获取大小的方法

    • 方法1:遍历文件夹下所有内容,计算相加

      // 总大小NSInteger size = 0;// 文件路径NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];NSString *file = [caches stringByAppendingPathComponent:@"default"];// 文件管理者NSFileManager *mgr = [NSFileManager defaultManager];// 获得文件夹中的所有内容//    NSArray *contents = [mgr contentsOfDirectoryAtPath:file error:nil];NSArray *subpaths = [mgr subpathsAtPath:file];for (NSString *subpath in subpaths) {    // 获得全路径    NSString *fullSubpath = [file stringByAppendingPathComponent:subpath];    // 获得文件属性    NSDictionary *attrs = [mgr attributesOfItemAtPath:fullSubpath error:nil];//     size += [attrs[NSFileSize] integerValue];    size += attrs.fileSize;}XMGLog(@"%@ %f", file, size / 1000.0 / 1000.0);
    • 方法2:引用遍历器/迭代器

  // 总大小  NSInteger size = 0;    // 文件路径    NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];    NSString *file = [caches stringByAppendingPathComponent:@"default"];   // 文件管理者   NSFileManager *mgr = [NSFileManager defaultManager];   // 获得文件夹中的所有内容   NSDirectoryEnumerator *enumerator = [mgr enumeratorAtPath:file];    for (NSString *subpath in enumerator) {       // 获得全路径       NSString *fullSubpath = [file stringByAppendingPathComponent:subpath];       // 获得文件属性       NSDictionary *attrs = [mgr attributesOfItemAtPath:fullSubpath error:nil];   //   size += [attrs[NSFileSize] integerValue];        size += attrs.fileSize;    }    XMGLog(@"%@ %f", file, size / 1000.0 / 1000.0);
  • 计算大小功能抽取分类,字符串做分类(方便)
    • 适用计算文件夹大小,如果是文件,没法输出大小,需要加判断
- (NSInteger)fileSize{    // 文件管理者    NSFileManager *mgr = [NSFileManager defaultManager];    // 是否为文件夹    BOOL isDirectory = NO;    // 这个路径是否存在    BOOL exists = [mgr fileExistsAtPath:self isDirectory:&isDirectory];    // 路径不存在    if (exists == NO) return 0;    if (isDirectory) { // 文件夹        // 总大小        NSInteger size = 0;        // 获得文件夹中的所有内容        NSDirectoryEnumerator *enumerator = [mgr enumeratorAtPath:self];        for (NSString *subpath in enumerator) {            // 获得全路径            NSString *fullSubpath = [self stringByAppendingPathComponent:subpath];            // 获得文件属性            size += [mgr attributesOfItemAtPath:fullSubpath error:nil].fileSize;        }        return size;    } else { // 文件        return [mgr attributesOfItemAtPath:self error:nil].fileSize;    }}
  • 封装一个清除缓存的操作,自定义cell
/** 缓存路径 */#define XMGCacheFile [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:@"default"]- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {        self.textLabel.text = XMGDefaultText;        // 禁止点击事件        self.userInteractionEnabled = NO;        // 右边显示圈圈        UIActivityIndicatorView *loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];        [loadingView startAnimating];        self.accessoryView = loadingView;        // 计算大小        [[[NSOperationQueue alloc] init] addOperationWithBlock:^{            // 计算缓存大小            NSInteger size = XMGCacheFile.fileSize;            CGFloat unit = 1000.0;            NSString *sizeText = nil;            // 文件大小显示格式            if (size >= unit * unit * unit) { // >= 1GB                sizeText = [NSString stringWithFormat:@"%.1fGB", size / unit / unit / unit];            } else if (size >= unit * unit) { // >= 1MB                sizeText = [NSString stringWithFormat:@"%.1fMB", size / unit / unit];            } else if (size >= unit) { // >= 1KB                sizeText = [NSString stringWithFormat:@"%.1fKB", size / unit];            } else { // >= 0B                sizeText = [NSString stringWithFormat:@"%zdB", size];            }            NSString *text = [NSString stringWithFormat:@"%@(%@)", XMGDefaultText, sizeText];            // 回到主线程            [[NSOperationQueue mainQueue] addOperationWithBlock:^{                self.textLabel.text = text;                self.accessoryType = UITableViewCellAccessoryDisclosureIndicator;                self.accessoryView = nil; // 圈圈消失                // 允许点击事件                self.userInteractionEnabled = YES;            }];        }];    }    return self;}
  • 取消cell选中时背景颜色
#pragma mark - <代理>- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{    // 取消选中    [tableView deselectRowAtIndexPath:indexPath animated:YES];    // 清除缓存    XMGClearCacheCell *cell = (XMGClearCacheCell *)[tableView cellForRowAtIndexPath:indexPath];    [cell clearCache];}
  • 模拟清除缓存操作
- (void)clearCache{    [SVProgressHUD showWithStatus:@"正在清除缓存" maskType:SVProgressHUDMaskTypeBlack];    [[[NSOperationQueue alloc] init] addOperationWithBlock:^{        [[NSFileManager defaultManager] removeItemAtPath:XMGCacheFile error:nil];        [[NSOperationQueue mainQueue] addOperationWithBlock:^{            [SVProgressHUD showSuccessWithStatus:@"清除成功"];            self.textLabel.text = XMGDefaultText;            // 禁止点击事件            self.userInteractionEnabled = NO;        }];    }];}

七 不同标识cell的共存

  • 当有多个样式不一样的cell时,不方便cell循环利用,可以通过注册2或多个cell(cellID)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    if (indexPath.section == 0 && indexPath.row == 0) { // 清除缓存的cell        XMGClearCacheCell *cell = [tableView dequeueReusableCellWithIdentifier:XMGClearCacheCellId]; //    [cell updateStatus];        return cell;    } else if (indexPath.section == 1 && indexPath.row == 2) {        return [tableView dequeueReusableCellWithIdentifier:XMGThirdCellId];    } else {        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:XMGOtherCellId];        cell.textLabel.text = [NSString stringWithFormat:@"%zd - %zd", indexPath.section, indexPath.row];        return cell;    }}
  • 一旦离开缓存池,cell一些动画会自动停掉,想要不停动画,更新状态
- (void)updateStatus{    if (self.accessoryView == nil) return;    // 让圈圈继续旋转    UIActivityIndicatorView *loadingView = (UIActivityIndicatorView *)self.accessoryView;    [loadingView startAnimating];}
2 0
原创粉丝点击