CategoryViewController.h
#import <UIKit/UIKit.h>
#import "QFHttpDownloadDelegate.h"@interface CategoryViewController : UITableViewController <QFHttpDownloadDelegate>
{
//保存所有分类信息
NSMutableArray * dataArray;
QFHttpDownload * httpDownload;
}
@end
CategoryViewController.m
#import "CategoryViewController.h"
#import "CategoryItem.h"
#import "RssItem.h"
#import "QFHttpDownload.h"
#import "NewsListViewController.h"
#import "GDataXMLNode.h"
@interface CategoryViewController ()
@end
@implementation CategoryViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
dataArray = [[NSMutableArray alloc] init];
httpDownload = [[QFHttpDownload alloc] init];
httpDownload.delegate = self;
[httpDownload downloadFromUrl:@"http://rss.sina.com.cn/sina_all_opml.xml"];
}
-(NSString *)elementAttr:(GDataXMLElement *)element name:(NSString *)name
{
//从当前节点中根据属性名获得属性值
GDataXMLNode * node = [element attributeForName:name];
return [node stringValue];
}
-(void)downloadComplete:(QFHttpDownload *)hd
{
GDataXMLDocument * doc = [[[GDataXMLDocument alloc] initWithData:hd.downloadData options:0 error:nil] autorelease];
if(doc){
//获得所有外层outline节点
NSArray * array = [doc nodesForXPath:@"/opml/body/outline" error:nil];
for(GDataXMLElement * element in array){
CategoryItem * citem = [[[CategoryItem alloc] init] autorelease];
citem.title = [self elementAttr:element name:@"title"];
NSMutableArray * subArray = [NSMutableArray array];
//遍历当前节点的所有子节点(内层outline)
for(GDataXMLElement * subElement in [element children]){
RssItem * ritem = [[[RssItem alloc] init] autorelease];
ritem.title = [self elementAttr:subElement name:@"title"];
ritem.url = [self elementAttr:subElement name:@"xmlUrl"];
[subArray addObject:ritem];
}
citem.subArray = subArray;
[dataArray addObject:citem];
}
[self.tableView reloadData];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [dataArray count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
CategoryItem * item = [dataArray objectAtIndex:section];
return [item.subArray count];
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
CategoryItem * item = [dataArray objectAtIndex:section];
return item.title;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
CategoryItem * cItem = [dataArray objectAtIndex:indexPath.section];
RssItem * rItem = [cItem.subArray objectAtIndex:indexPath.row];
cell.textLabel.text = rItem.title;
cell.detailTextLabel.text = rItem.url;
return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 60.0f;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NewsListViewController * nlvc = [[NewsListViewController alloc] initWithStyle:UITableViewStylePlain];
CategoryItem * cItem = [dataArray objectAtIndex:indexPath.section];
RssItem * rItem = [cItem.subArray objectAtIndex:indexPath.row];
nlvc.url = rItem.url;
[self.navigationController pushViewController:nlvc animated:YES];
[nlvc release];
}
@end
NewsListViewController.h
#import <UIKit/UIKit.h>
#import "QFHttpDownloadDelegate.h"
#import "EGORefreshTableHeaderView.h"
@interface NewsListViewController : UITableViewController <QFHttpDownloadDelegate, EGORefreshTableHeaderDelegate>
{
NSMutableArray * dataArray;
QFHttpDownload * httpDownload;
NSUInteger curPage; //当前页码
NSUInteger pageCount; //总页数
NSUInteger perPageCount;//每页的数据条数
BOOL isLoading; //是否正在请求数据
//下拉刷新视图
EGORefreshTableHeaderView * refreshView;
}
//当前分类源地址
@property (nonatomic, copy) NSString * url;
@property (nonatomic, retain) NSMutableArray * curPageArray;//当前页码的数据
@end
NewsListViewController.m
#import "NewsListViewController.h"
#import "NewsItem.h"
#import "QFHttpDownload.h"
#import "GDataXMLNode.h"
#import "NewsCell.h"
@interface NewsListViewController ()
@end
@implementation NewsListViewController
@synthesize url = _url;
@synthesize curPageArray = _curPageArray;
-(void)dealloc
{
httpDownload.delegate = nil;
[httpDownload release];
[super dealloc];
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
UIBarButtonItem * leftitem = [[UIBarButtonItem alloc] initWithTitle:@"前一页" style:UIBarButtonItemStyleDone target:self action:@selector(perClicked:)];
self.navigationItem.leftBarButtonItem = leftitem;
[leftitem release];
UIBarButtonItem * rightitem = [[UIBarButtonItem alloc] initWithTitle:@"后一页" style:UIBarButtonItemStyleDone target:self action:@selector(nextClicked:)];
self.navigationItem.rightBarButtonItem = rightitem;
[rightitem release];
}
return self;
}
-(void)perClicked:(UIBarButtonItem *)item
{
if(isLoading){
return;
}
if([item.title isEqualToString:@"Back"]){
[self.navigationController popToRootViewControllerAnimated:YES];
}
curPage--;
if(curPage < 1){
curPage = 1;
[item setTitle:@"第一页"];
}
}
-(void)nextClicked:(UIBarButtonItem *)item
{
if(isLoading){
return;
}
curPage++;
if(curPage > pageCount){
curPage = pageCount;
}
// [self loadData:curPage count:perPageCount];
}
- (void)viewDidLoad
{
[super viewDidLoad];
dataArray = [[NSMutableArray alloc] initWithCapacity:0];
httpDownload = [[QFHttpDownload alloc] init];
httpDownload.delegate = self;
[httpDownload downloadFromUrl:self.url];
isLoading = YES;
CGRect frame = self.tableView.frame;
frame.origin.y -= (frame.size.height + 24);
refreshView = [[EGORefreshTableHeaderView alloc] initWithFrame:frame];
refreshView.delegate = self;
[self.tableView addSubview:refreshView];
//最新刷新时间
[refreshView refreshLastUpdatedDate];
curPage = 1;
perPageCount = 10;
pageCount = 888888;
}
//滚动视图发生滚动
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[refreshView egoRefreshScrollViewDidScroll:scrollView];
}
//停止拖拽
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
[refreshView egoRefreshScrollViewDidEndDragging:scrollView];
}
//当前是否正在刷新
-(BOOL)egoRefreshTableHeaderDataSourceIsLoading:(EGORefreshTableHeaderView *)view
{
return isLoading;
}
//最后刷新时间
-(NSDate *)egoRefreshTableHeaderDataSourceLastUpdated:(EGORefreshTableHeaderView *)view
{
return [NSDate date];
}
//在此方法中重新加载数据(触发了刷新)
-(void)egoRefreshTableHeaderDidTriggerRefresh:(EGORefreshTableHeaderView *)view
{
[self nextClicked:nil];
}
-(void)viewDidDisappear:(BOOL)animated
{
httpDownload.delegate = nil;
[super viewDidDisappear:animated];
}
//获得节点element的指定的子节点(name)的值(文本信息)
-(NSString *)element:(GDataXMLElement *)element name:(NSString *)name
{
NSArray * array = [element elementsForName:name];
GDataXMLElement * subElement = [array lastObject];
return [subElement stringValue];
}
-(void)downloadComplete:(QFHttpDownload *)hd
{
GDataXMLDocument * doc = [[GDataXMLDocument alloc] initWithData:hd.downloadData options:0 error:nil];
if(doc){
NSArray * array = [doc nodesForXPath:@"//item" error:nil];
for(GDataXMLElement * itemElement in array){
NewsItem * item = [[[NewsItem alloc] init] autorelease];
item.title = [self element:itemElement name:@"title"];
item.summary = [self element:itemElement name:@"description"];
item.link = [self element:itemElement name:@"link"];
item.pubdate = [self element:itemElement name:@"pubDate"];
[dataArray addObject:item];
}
[self.tableView reloadData];
}else{
NSLog(@"没有数据");
}
//通知下拉刷新视图结束
[refreshView egoRefreshScrollViewDataSourceDidFinishedLoading:self.tableView];
isLoading = NO;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [dataArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
// UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//
// if(nil == cell){
// cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
// }
// NewsItem * item = [dataArray objectAtIndex:indexPath.row];
// cell.textLabel.text = item.title;
// cell.textLabel.numberOfLines = 0;
// cell.detailTextLabel.text = [NSString stringWithFormat:@"%@\n%@", item.summary, item.link];
// cell.detailTextLabel.numberOfLines = 5;
NewsCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(nil == cell){
cell = [[[NSBundle mainBundle] loadNibNamed:@"NewsCell" owner:self options:nil] lastObject];
}
NewsItem * item = [dataArray objectAtIndex:indexPath.row];
cell.titleLabel.numberOfLines = 0;
cell.titleLabel.text = item.title;
//设置计算高度时的参数
cell.summaryLabel.font = [UIFont systemFontOfSize:14];
cell.summaryLabel.lineBreakMode = NSLineBreakByCharWrapping;
//设置行数为0,有多少显示多少
cell.summaryLabel.numberOfLines = 0;
//得新设置标签的高度
CGRect frame = cell.summaryLabel.frame;
frame.size.height = item.height;
cell.summaryLabel.frame = frame;
cell.summaryLabel.text = item.summary;
cell.linkLabel.text = item.link;
cell.pubDateLabel.text = [NSString stringWithFormat:@"北京发布时间: %@", item.pubdate];
cell.pubDateLabel.font = [UIFont systemFontOfSize:13];
return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NewsItem * item = [dataArray objectAtIndex:indexPath.row];
if([item.summary isEqualToString:@""]){
return 49 + [item height] + 10;
}
return 100 + [item height] + 49;
}
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row % 4 == 0){
cell.backgroundColor = [UIColor greenColor];
}else if(indexPath.row % 4 == 1){
cell.backgroundColor = [UIColor purpleColor];
}else if(indexPath.row % 4 == 2){
cell.backgroundColor = [UIColor yellowColor];
}else{
cell.backgroundColor = [UIColor orangeColor];
}
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
*/
}
@end
CategoryItem.h
#import <Foundation/Foundation.h>
@interface CategoryItem : NSObject
//一级分类名
@property (nonatomic, copy) NSString * title;
//子分类的信息数组
@property (nonatomic, retain) NSArray * subArray;
@end
CategoryItem.m
#import "CategoryItem.h"
@implementation CategoryItem
@synthesize title = _title;
@synthesize subArray = _subArray;
-(void)dealloc
{
self.title = nil;
self.subArray = nil;
[super dealloc];
}
@end
RssItem.h
#import <Foundation/Foundation.h>
@interface RssItem : NSObject
//子分类标题
@property (nonatomic, copy) NSString * title;
//子分类的地址
@property (nonatomic, copy) NSString * url;
@end
RssItem.m
#import "RssItem.h"
@implementation RssItem
@synthesize title = _title;
@synthesize url = _url;
-(void)dealloc
{
self.title = nil;
self.url = nil;
[super dealloc];
}
@end
NewsItem.h
#import <Foundation/Foundation.h>
@interface NewsItem : NSObject
@property (nonatomic, copy) NSString * title;
@property (nonatomic, copy) NSString * pubdate;
@property (nonatomic, copy) NSString * summary;
@property (nonatomic, copy) NSString * link;
//获得动态信息的高度
-(CGFloat)height;
@end
NewsItem.m
#import "NewsItem.h"
@implementation NewsItem
@synthesize title = _title;
@synthesize link = _link;
@synthesize summary = _summary;
@synthesize pubdate = _pubdate;
-(void)dealloc
{
self.title = nil;
self.link = nil;
self.summary = nil;
self.pubdate = nil;
[super dealloc];
}
-(CGFloat)height
{
//根据字体,显示的宽度,以及换行方式计算字符串高度
CGSize size = [self.summary sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(300, CGFLOAT_MAX) lineBreakMode:NSLineBreakByCharWrapping];
return size.height;
}
@end
NewsCell.h
#import <UIKit/UIKit.h>
@interface NewsCell : UITableViewCell
@property (retain, nonatomic) IBOutlet UILabel *titleLabel;
@property (retain, nonatomic) IBOutlet UILabel *summaryLabel;
@property (retain, nonatomic) IBOutlet UILabel *linkLabel;
@property (retain, nonatomic) IBOutlet UILabel *pubDateLabel;
@end
NewsCell.m
#import "NewsCell.h"
@implementation NewsCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)dealloc {
[_titleLabel release];
[_summaryLabel release];
[_linkLabel release];
[_pubDateLabel release];
[super dealloc];
}
@end