UI一揽子计划 20 (豆瓣实战之图片缓存 、豆瓣实战之详情界面(自适应行高) 、豆瓣实战之登陆注销、刘新林分享之UIAlertController)

一.图片缓存


ActivityModel.m

如果数据加载完毕就将图片放到缓存中.
#pragma mark -- imageDownLoader 代理方法
//  成功返回data
- (
void)imageDownSucceedWithData:(NSData *)data
{
   
//  model里的图片 赋值
   
self.getUrlImage = [UIImage imageWithData:data];
   
//  标识加载完毕
   
_isDownloading = NO;
   
//  图片缓存
   
FileManager *manager = [FileManager shareManager];
    [manager
saveImageData:data imageURl:self.image];
}

在给model对象赋值的时候, 用的是KVC 方法,其实内部调用的是setValue forKey 的方法.所以就改写里面的方法,如果缓存区里有图片就不从网上download,直接从缓存路径下面去读取图片.
读缓存的思路
        1.
图片显示在 cell , 需要看显示图片的方法
        2.
model 中的 getUrlImage 为空的时候是去请求图片的 ,
        3.
现在需要加载缓存 .
        4.
不请求 就是 model 中的 getUrlImage 不为空
        5.
如果给 getUrlImage 赋值 缓存中的图片 达到目的了
        6.
新问题 : 如何给 getUrlImage 赋值 缓存中的图片 ?
        7.
利用图片的 网址 可以找到对应的缓存图片
        8.
如何在一开始赋值的时候 就把缓存中的图片赋值 model
        9. 一开始的赋值 setValue ForKey 方法中

//setValueforkeywithDictionary:Dic  实际上多次调用下面的方法
- (
void)setValue:(id)value forKey:(NSString *)key
{
    [super setValue:value forKey:key];
  if([key isEqualToString:@"image"]) {
        // 这时 value 就是图片的网址
        self.image = value;
        // self.getUrlImage 加载缓存
       
self.imagePath = [[FileManager shareManager] imagesPathWithImageUrl:self.image];
       
self.getUrlImage = [UIImage imageWithContentsOfFile:self.imagePath];
    }
}

FileManager.h
#import <Foundation/Foundation.h>
@interface FileManager : NSObject
+ (
FileManager *)shareManager;
- (
void)saveImageData:(NSData *)imageData imageURl:(NSString *)imageUrl;
// url 返回一个URL 完整路径
- (
NSString *)imagesPathWithImageUrl:(NSString *)imageUrl;
@end

FileManager.m
#import "FileManager.h"
@implementation FileManager
+ (
FileManager *)shareManager
{
   
static FileManager *manager = nil;
   
if (manager == nil) {
        manager = [[
FileManager alloc]init];
    }
   
return manager;
}
// 1. 把文件夹创建在沙盒的缓存文件夹里

// 2. 需要把图片的网址变成图片名字 然后拼接成地址

// 3. 把图片写进文件 按完整地址(文件夹 + 名字)
// 返回cache文件夹的路径
- (
NSString *)cachesPath
{
   
NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
   
NSLog(@"%@", cachePath);
   
return cachePath;
}
// cache文件夹下创建一个ImageDownload文件夹
- (
NSString *)createImageDownloadFile
{
   
NSString *imageDownloadPath = [[self cachesPath] stringByAppendingPathComponent:@"ImageDownload"];
   
NSFileManager *manager = [NSFileManager defaultManager];
   
// 判断文件夹是否存在
   
if ([manager isExecutableFileAtPath:imageDownloadPath] == NO) {
       
// 文件夹不存在 就创建一个
        [manager
createDirectoryAtPath:imageDownloadPath withIntermediateDirectories:YES attributes:nil error:nil];
    }
   
return imageDownloadPath;
}
// 图片的路径 需要图片的网址 文件夹的路径
- (
NSString *)imagesPathWithImageUrl:(NSString *)imageUrl
{
   
// 转换图片的名字 "/"转换成"_"
   
NSString *imageName = [imageUrl stringByReplacingOccurrencesOfString:@"/" withString:@"_"];
   
// 拼接完整的路径
   
NSString *imagePath = [[self createImageDownloadFile] stringByAppendingPathComponent:imageName];
   
return imagePath;
}
// 利用路径保存图片的data
- (
void)saveImageData:(NSData *)imageData imageURl:(NSString *)imageUrl
{
   
// 保存的前提是要有文件夹
   
//NSString *imageDownloadPath = [self createImageDownloadFile];
   
// 得到图片的路径
   
NSString *imagePath = [self imagesPathWithImageUrl:imageUrl];
   
   
// 写文件
    [imageData
writeToFile:imagePath atomically:YES];
}
@end

详情界面中加载图片的方法(两种情况)

1. 如果图片加载出来了,就把model的图片属性传过来
2. 如果图片还没有加载出来 model的图片属性为空 那么就设置观察者模式 观察这个图片属性 如果图片加载出来 就给图片赋值
// 活动图片
    if (self.model.getUrlImage == nil) {
       
//没有图像,下载图像
        view.
activityImageView.image = [UIImage imageNamed:@"picholder"];
        [
self.model imageDownload];
       
// 添加一个观察者来观察图片是否已经加载出来了
        [
self.model addObserver:self forKeyPath:@"getUrlImage" options:NSKeyValueObservingOptionNew context:nil];
    }
else{
        view.
activityImageView.image = self.model.getUrlImage;
    }
//添加观察者
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    ActivityDetailView *view = (ActivityDetailView *)self.view;
    UIImage *image = [change objectForKey:NSKeyValueChangeNewKey];  
    view.activityImageView.image = image;   
}

二.详情界面
详情界面中对scrollView 自适应行高
- (void)adjustSubviewsWithContent:(NSString *)content
{
   
//计算活动内容的高度
   
CGRect frame = [content boundingRectWithSize:CGSizeMake(_titleLabel.width, 10000000) options:(NSStringDrawingUsesLineFragmentOrigin) attributes:[NSDictionary dictionaryWithObject:[UIFont systemFontOfSize:12] forKey:NSFontAttributeName] context:nil];
    // 更改label的高度 然后再更改 scrollView的高度  显示滑动范围
    _contextLabel.height = frame.size.height;
    _bottomScrollView.contentSize = CGSizeMake(kScreenWidth, _contextLabel.bottom + 20);
}

三.登陆注销
UserManager.h
#import <Foundation/Foundation.h>
@interface UserManager : NSObject
+(
UserManager *)shareUserManager;
// 传进来一个账号 把账号持久化
- (
void)userName:(NSString *)userName;
// 返回账号信息
- (
NSString *)userName;
- (
void)password:(NSString *)passord;
- (
NSString *)password;
- (
void)isLogin:(BOOL)isLogin;
- (
BOOL)isLogin;
@end

UserManager.m
#import "UserManager.h"
@implementation UserManager
+(
UserManager *)shareUserManager
{
   
static UserManager *manager = nil;
   
if (manager == nil) {
        manager = [[
UserManager alloc]init];
    }
   
return manager;
}
// 传进来一个账号 把账号持久化
- (
void)userName:(NSString *)userName
{
   
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    [userDefaults
setObject:userName forKey:kUserName];
   
// 同步数据
    [userDefaults
synchronize];
}
// 返回账号信息
- (
NSString *)userName
{
   
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
   
return [userDefaults objectForKey:kUserName];
}
- (
void)password:(NSString *)passord
{
    [[
NSUserDefaults standardUserDefaults] setObject:passord forKey:kPassword];
    [[
NSUserDefaults standardUserDefaults] synchronize];
}

- (
NSString *)password
{
   
return [[NSUserDefaults standardUserDefaults] objectForKey:kPassword];
}
- (
void)isLogin:(BOOL)isLogin
{
    [[
NSUserDefaults standardUserDefaults] setBool:isLogin forKey:kLoginState];
    [[
NSUserDefaults standardUserDefaults]synchronize];
}
- (
BOOL)isLogin
{
   
return [[NSUserDefaults standardUserDefaults]boolForKey:kLoginState];
}
@end


四.UIAlertController
- (void)viewDidLoad {
    [
super viewDidLoad];
   
   
UIButton *button = [UIButton buttonWithType:(UIButtonTypeCustom)];
    button.
frame = CGRectMake(100, 100, 100, 100);
    [button
setTitle:@"点击" forState:(UIControlStateNormal)];
    button.
backgroundColor = [UIColor redColor];
    [button
addTarget:self action:@selector(action:) forControlEvents:(UIControlEventTouchUpInside)];
    [self.view addSubview:button];
}

- (
void)action:(UIButton *)button
{
   
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"提示" message:@"我是alert" preferredStyle:(UIAlertControllerStyleAlert)];
   
// 创建一个按钮
   
// handler  处理点击事件
   
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction *action) {
       
// block 回调
     NSLog(@"%@",action.title);
    }];
   
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:(UIAlertActionStyleCancel) handler:^(UIAlertAction *action) {
        // block 回调
        NSLog(@"%@",action.title);
    }];
    [alertVC addAction:okAction];
    [alertVC
addAction:cancelAction];
   
    [alertVC
addTextFieldWithConfigurationHandler:^(UITextField *textField) {
       textField.text = @"wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww";   
    }];
    NSArray *textFieldArray = alertVC.textFields;
    NSLog(@"%@", textFieldArray[0]); // 数组里面存放的是字典
/ <_UIAlertControllerTextField: 0x7f986a8365a0; frame = (0 0; 0 0); text = 'wwwwwwwwwwwwwwwwwwwwwwwww...'; clipsToBounds = YES; opaque = NO; layer = <CALayer: 0x7f98684485f0>>/
    [self presentViewController:alertVC animated:YES completion:nil];
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值