iOS ——KVO 监测Model 图片下载

27 篇文章 0 订阅

前言
UItableView中 ableView:cellForRowAtIndexPath:会在重⽤用的时候,根据Model显示image或者placeholderImage。
如果tableView并未滑动,此时有图⽚片下载完毕,是不会⽴立即更新到
cell上的。
实现方法:
1.tableView:cellForRowAtIndexPath:中,为Model的image属性添加
观察者。
2.image属性由nil变为非空的时候,视图控制器根据indexPath更新cell 显⽰示,
注意:图片未下载完成时显示默认图片; 图片下载完成后只更新当前显示的cell ,显示到哪更新到哪。
实现方法1.
具体代码:

News 类
@property (nonatomic, strong) NSString * picUrl;
//图片属性
@property (nonatomic, strong) UIImage * newsImage;
//图片下载状况
@property (nonatomic, assign) BOOL isDownloading;

//图片下载方法
-(void)loadImage
{
//    使用图片下载器,根据图片链接给model 对象下载图片。
 [GreenDownImage downloadImageWithURLString:_picUrl block:^(UIImage *image) {
     self.newsImage = image;
//     下载完之后才执行
     _isDownloading = NO; 
 }];
//    先走外面 图片正在下载
    _isDownloading = YES;
}
#import "RootTableViewController.h"
#import "MyCell.h"
#import "News.h"
#import "UIImageView+WebCache.h"
//图片网址
#define BASE_URL @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx?date=20150921&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213"

@interface RootTableViewController ()
@property (nonatomic, strong) NSMutableArray * allDataArray;
@end

@implementation RootTableViewController
static NSString * const cellID = @"MyCellID";

- (void)viewDidLoad {
    [super viewDidLoad];

//    解析数据 (获得图片的url)
    NSURLRequest * request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:BASE_URL]];

    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

        NSDictionary * dict= [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
        _allDataArray = [[NSMutableArray alloc] initWithCapacity:30];
        for (NSDictionary * dic in [dict objectForKey:@"news"]) {
            News * news = [News new];
            [news setValuesForKeysWithDictionary:dic];
            [_allDataArray addObject:news];
        }
        [self.tableView reloadData];
    }]; 
   }

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [_allDataArray count];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 250;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    MyCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID forIndexPath:indexPath];

//    取出model 对象
   News * news = _allDataArray[indexPath.row];

//    图片为空,并且没有在下载状态 (第一次刚开始运行的时候)
    if (news.newsImage==nil && news.isDownloading == NO) {
//        设置默认图片
         cell.photoView.image = [UIImage imageNamed:@"1"];
//       调用下载方法 让其自行下载图片
        [news loadImage];
//        设置观察者(观察是否完成)给cell 添加的数据
        [news addObserver:self forKeyPath:@"newsImage" options:NSKeyValueObservingOptionNew context:(__bridge void *)(indexPath)];
    }else{
//       news 的image 为空 但是正在下载
        if (news.newsImage == nil) {
            cell.photoView.image =[UIImage imageNamed:@"1"];
        }else{
//          下载完成 (图片不为空)设置图片
            cell.photoView.image = news.newsImage;
        }
    }
    return cell;
}
//实现监测方法 , 实现只显示当前显示的cell
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
//    图片为空,
    UIImage * image = (UIImage *)change [@"news"];
    if (image == nil) {
        return;
    }
//      取出可视区域cell位置的集合
    NSArray * array =  [self.tableView indexPathsForVisibleRows];
//    获取被观察的model 对象
    NSIndexPath * indexPath = (__bridge NSIndexPath *)(context);
//    判断被观察的cell 是否在可视区域
    if ([array containsObject:indexPath]) {
// 如果在显示区域,取出对应的cell 更新数据。
        MyCell * cell = (MyCell *)[self.tableView cellForRowAtIndexPath:indexPath];
        cell.photoView.image = image;
//        更新cell
        [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
    }
//    移除观察者
    [object removeObserver:self forKeyPath:@"newsImage"];
}

方法二:第三方
以上功能可以使用第三方轻易实现
1. 下载 网址:http://download.csdn.net/detail/ci915194561/9142913
2. 导入#import “UIImageView+WebCache.h”
3. 使用

// 使用第三方。(imageView ) url 是图片地址字符串。 image 是默认图片。
    [cell.photoView sd_setImageWithURL:[NSURL URLWithString:news.picUrl] placeholderImage:[UIImage imageNamed:@"1"]];

有关于KVO详细介绍 请见另一篇博客:http://blog.csdn.net/ci915194561/article/details/48767511

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值