Three20 – TableView(TTTableViewController)(2)

上次笔记了一下一般的TableView怎么弄,搞了搞,继续深入了研究了一下,看到很多app都有“下拉刷新”的功能,比如人人的app,还有qq空间的app,觉得很酷,那么我们怎么用320来实现一下呢,就看看我下面这个笔记吧。

首先,创建项目,我这里创建了一个叫freshtest的项目,然后把320的引入,ok,看看能不能build,能build就说明引入成功了,成功之后我们就开始写一个320的TableView,具体怎么写在这篇文章里面 已经写了,这个地方的代码我就不过多重复了。写好后,先看看能不能运行,应该是下面这个效果。

好吧,运行成功之后,我们需要在RootViewController里加上这样一段代码。

- (id)createDelegate {
return [[[TTTableViewDragRefreshDelegate alloc] initWithController:self] autorelease];
}

嗯,试试运行,看看把tableview往下拉,能不能看到一个很眼熟的“下拉后更新”呢,可以吧,是不是这段代码很牛x?但是先别乐,因为这个只是展现了一个view,并没有做什么事情,不信你下拉一下,或者用抓包工具抓包一下,看看做了什么。实际上,什么也没做!

所以,要到达做事情的地步还远着呢。上面的代码只是申明了一个委托,还没又实际作用,因为我们还要写datasource,model来实现细节,现在才刚刚开始,我们来实现细节。

我们就先什么也不干,请求一个网站然后让这个东西先运作起来。我们暂时目标就定做请求一个Feed,我们先写个Feed类,我们先创建一个Feed类,然后编写代码如下。

头文件。

#import < Three20 / Three20.h >

@interface Feed : NSObject {
    NSString* _text;
    NSString
* _source;
    NSString
* _ftype;
    NSString
* _img;
}

@property (nonatomic, copy)   NSString* text;
@property (nonatomic, copy)   NSString
* source;
@property (nonatomic, copy)   NSString
* ftype;
@property (nonatomic, copy)   NSString
* img;

 
@end

实现。

#import " Feed.h "

@implementation Feed

@synthesize text      = _text;
@synthesize source    
= _source;
@synthesize ftype    
= _ftype;
@synthesize img
= _img;

- ( void ) dealloc {
    TT_RELEASE_SAFELY(_text);
    TT_RELEASE_SAFELY(_source);
    TT_RELEASE_SAFELY(_ftype);
    TT_RELEASE_SAFELY(_img);
    [super dealloc];
}

@end 

上面只是一个很简单的Feed类,我们实现之后,就需要写一个Model了,创建一个Model类,实现如下。

头文件。

#import < Three20 / Three20.h >

@interface Model : TTURLRequestModel {
    NSString* _searchQuery;
    NSArray
*   _feeds;
}

@property (nonatomic, copy)     NSString* searchQuery;
@property (nonatomic,
readonly ) NSArray *   feeds;

- (id)initWithSearchQuery:(NSString * )searchQuery;

@end 

具体实现。

#import " Model.h "
#import
" Feed.h "

@implementation Model

@synthesize searchQuery = _searchQuery;
@synthesize feeds      
= _feeds;

- (id)initWithSearchQuery:(NSString * )searchQuery {
    
if (self = [super init]) {
        self.searchQuery
= searchQuery;
    }
    
    
return self;
}

- ( void ) dealloc {
    TT_RELEASE_SAFELY(_searchQuery);
    TT_RELEASE_SAFELY(_feeds);
    [super dealloc];
}

- ( void )load:(TTURLRequestCachePolicy)cachePolicy more:(BOOL)more {
    
if ( ! self.isLoading && TTIsStringWithAnyText(_searchQuery)) {
        NSString
* url = @" http://api.douban.com/people/2449296/miniblog/contacts/merged?alt=json&max-results=20 " ;
        
        TTURLRequest
* request = [TTURLRequest
                                 requestWithURL: url
                                
delegate : self];
        
        request.cachePolicy
= cachePolicy;
        request.cacheExpirationAge
= TT_CACHE_EXPIRATION_AGE_NEVER;
        [request send];
    }
}

- ( void )requestDidFinishLoad:(TTURLRequest * )request {
}

@end 

其中,load方法和requestDidFinishLoad很重要,我们现在requestDidFinishLoad可以暂时什么都不实现,就这样空着。剩下,我们再写一个DataSource,作为TableView的数据源。ok,依然上代码。

头文件。

#import < Three20 / Three20.h >

@class Model;
// TTListDataSource
@interface DataSource : TTSectionedDataSource {
    Model
* _feed_model;
}

- (id)initWithSearchQuery:(NSString * )searchQuery;

@end 

记得上面的代码是继承自TTSectionedDataSource的,在demo中是继承自TTListDataSource,当然,这两个都是 可以的,但是还是有区别的,继承自TTListDataSource的话,就是普通的TableView。而继承自 TTSectionedDataSource的话,是可以有分类标题的,下回再说。

继续实现。

#import " DataSource.h "
#import
" Model.h "
#import
" Feed.h "

@implementation DataSource

- (id)initWithSearchQuery:(NSString * )searchQuery {
    
if (self = [super init]) {
        _feed_model
= [[Model alloc] initWithSearchQuery:searchQuery];
    }
    
return self;
}

- ( void )dealloc {
    TT_RELEASE_SAFELY(_feed_model);
    
    [super dealloc];
}

- (id < TTModel > )model {
    
return _feed_model;
}

- ( void )tableViewDidLoadModel:(UITableView * )tableView {
}

- (NSString * )titleForLoading:(BOOL)reloading {
    
if (reloading) {
        
return NSLocalizedString( @" Updating feed… " , @" Feed updating text " );
    }
else {
        
return NSLocalizedString( @" Loading feed… " , @" Feed loading text " );
    }
}

- (NSString * )titleForEmpty {
    
return NSLocalizedString( @" No feed found. " , @" Feed no results " );
}

- (NSString * )subtitleForError:(NSError * )error {
    
return NSLocalizedString( @" Sorry, there was an error loading the Feed stream. " , @"" );
}


@end

实现完了,我们再改我们的RootViewController,改的地方不多,我们就改m文件就行了。先增加一个import。

#import “DataSource.h”

然后在修改createModel方法。

-(void)createModel {
self.dataSource = [[[DataSource alloc] initWithSearchQuery:@”haha”] autorelease];
}

运行试试看,是不是有一个loading界面?怎么没东西。

没关系,我们现在来解决它。实际上很简单,我们先开始留着的几个代码现在要实现,主要实现的是Model里的requestDidFinishLoad方法和DataSource里的tableViewDidLoadModel方法。

Model方法实现如下。

- (void)requestDidFinishLoad:(TTURLRequest*)request {
NSMutableArray* feeds = [[NSMutableArray alloc] initWithCapacity:1];
Feed* f = [[Feed alloc] init];
f.text = @”Hi”;
[feeds addObject:f];
_feeds = feeds;
[super requestDidFinishLoad:request];
}

然后再实现DataSource。

- (void)tableViewDidLoadModel:(UITableView*)tableView {
NSMutableArray* items = [[NSMutableArray alloc] init];
for(Feed *f in _feed_model.feeds) {
[items addObject:[TTTableTextItem itemWithText:f.text]];
}
self.items = items;
}

然后再运行,嗯,是不是出现了一个HI?然后再下拉看看,是不是很明显,出现了load的感觉,而且更新时间也有了变化?

如果这样,我们就程序就OK了,不过,如果想按照分类显示的话(像联系人那样),还需要改一些东西。下篇文章我会说说这个,然后说说如何真正请求网 上的API然后parse之后展现到View里面,其实这里已经说的比较明显了,但是还是应该提一下,有些小的很magic的地方。:)

代码样例可以看这里

本文转载自http://www.jguoer.com/blog/index.php/archives/1368

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值