zoukankan      html  css  js  c++  java
  • 320学习笔记 2

    20110625

    http://www.cnblogs.com/scorpiozj/archive/2011/06/27/2091259.html

    做iphone的,UINavigationController+UItableViewController组合的应用是必须会的,那么我们必须学习下如何使用320来实现此类应用。

    考虑这样的需求:点击tableview上的feed行就从apple store上获取排名前10的专辑信息,链接:http://itunes.apple.com/us/rss/topalbums/limit=10/explicit=true/xml.  具体流程:程序启动后是一tableview(图1),点击rss 后在tableview中显示所有专辑信息,每个cel(图2)l中左边是专辑图片,右上是歌手名,右下是专辑名.流程很简单,页面显示就两个:通常rooview+detailView就搞定,此外还需要一个获取数据的类就OK了.参考了320的一种现成的cell式样,好像没有和我们所需相同的,那么我们需要自定义cell.

     图1

    图2

    在开始工程前,我们首先看一下320中实现上述的tableview的一个大致框架(图3):

    图3

    在UIKit下,tableview的实现主要通过设置tableview的datasource和delegate,这是苹果典型的MVC思维。在320中也贯彻了MVC思想:需要tableviewController,dataSource,tableItem,tableItemCell,Model以及object。datasource,顾名思义是为tableview提供数据,它首先生成model来获得所需数据(FeedObj),然后根据原数据的类型生成相应的tableItem,最后根据tableItem来选择合适的tableItemCell。

    下面我们开始创建工程,可以选择xcode的viewController模板,然后将320添加进工程(过程略,参见官方的脚本文件).做好以上设置后,就可以开始了.我们大概需要以下类文件:rootViewController,tableViewController,tableItem,tableItemCell,Model,dataSource和obj.

    以下将代码列出,并做简单说明.

    MyThree20ProjAppDelegate主要的操作是生成url映射.

    MyThree20ProjAppDelegate
    #import <UIKit/UIKit.h>

    @class MyThree20ProjViewController;

    @interface MyThree20ProjAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow
    *window;
    MyThree20ProjViewController
    *viewController;
    }

    @property (nonatomic, retain) IBOutlet UIWindow
    *window;
    @property (nonatomic, retain) IBOutlet MyThree20ProjViewController
    *viewController;

    @end


    #import "MyThree20ProjAppDelegate.h"
    #import "MyThree20ProjViewController.h"

    #import <Three20/Three20.h>



    @implementation MyThree20ProjAppDelegate

    @synthesize window;
    @synthesize viewController;

    - (void)applicationDidFinishLaunching:(UIApplication *)application {
    TTNavigator
    *navigator = [TTNavigator navigator];
    navigator.persistenceMode
    = TTNavigatorPersistenceModeAll;
    navigator.window
    = self.window;

    TTURLMap
    *map = navigator.URLMap;

    // Any URL that doesn't match will fall back on this one, and open in the web browser
    // [map from:@"*" toViewController:[TTWebController class]];

    [map from:
    @"tt://root" toSharedViewController:NSClassFromString(@"MyThree20ProjViewController")];

    [map from:
    @"tt://feed" toSharedViewController:NSClassFromString(@"RssFeedTableViewController")];
    if (![navigator restoreViewControllers]) {
    [navigator openURLAction:[TTURLAction actionWithURLPath:
    @"tt://root"]];
    }
    }

    - (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)URL {
    [[TTNavigator navigator] openURLAction:[TTURLAction actionWithURLPath:URL.absoluteString]];
    return YES;
    }

    - (void)dealloc {
    [viewController release];
    [window release];
    [super dealloc];
    }

    接着就是熟悉的RootViewController,这里生成一个tableview

    MyThree20ProjViewController
    #import <UIKit/UIKit.h>

    @interface MyThree20ProjViewController : TTTableViewController {

    }

    @end

    #import "MyThree20ProjViewController.h"


    @implementation MyThree20ProjViewController


    - (void)viewDidLoad {
    [super viewDidLoad];

    self.title
    = @"My Three20";


    self.dataSource
    = [TTSectionedDataSource dataSourceWithObjects:
    @"F",
    [TTTableTextItem itemWithText:
    @"feed" URL:@"tt://feed"],
    nil];

    }


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

    @end

    RssFeedTableViewController,是320中tableViewController的子类,可以通过不同的datasource显示不同的view.

    RssFeedTableViewController
    #import <UIKit/UIKit.h>


    @interface RssFeedTableViewController : TTTableViewController {

    }

    @end

    #import "RssFeedTableViewController.h"
    #import "RssFeedDataSource.h"

    @implementation RssFeedTableViewController


    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self
    = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
    // Custom initialization.
    self.title = @"Rss";
    self.variableHeightRows
    = YES;//很重要,否则cell高度无法改变
    }
    return self;
    }

    - (void)createModel {

    self.dataSource
    = [[[RssFeedDataSource alloc] init] autorelease];

    }

    - (id<UITableViewDelegate>)createDelegate {
    return [[[TTTableViewDragRefreshDelegate alloc] initWithController:self] autorelease];//下拉刷新,但本文未实现
    }


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

    @end

    我们接着看下RssFeedDataSource,因为我们的tableview不需要section,所以是listdatasource的子类.通过model来获取所需数据,并生成相应的tableItem对象集合

    RssFeedDataSource
    #import <Foundation/Foundation.h>

    #import "RssFeedModel.h"

    @interface RssFeedDataSource : TTListDataSource {

    RssFeedModel
    *_feedModel;
    }

    -(id)initWithQuery:(NSString *)query;
    @end

    #import "RssFeedDataSource.h"
    #import "RssFeedObject.h"

    #import "RssTableItem.h"
    #import "RssTableItemCell.h"

    @implementation RssFeedDataSource

    -(id) init
    {
    if (self = [super init])
    {
    _feedModel
    = [[RssFeedModel alloc] initWithSearchQuery:@"a"];
    }

    return self;
    }

    -(id)initWithQuery:(NSString *)query
    {
    if (self = [super init])
    {
    _feedModel
    = [[RssFeedModel alloc] initWithSearchQuery:query];
    }
    return self;
    }

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

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

    - (void)tableViewDidLoadModel:(UITableView*)tableView
    {
    NSMutableArray
    *items = [[NSMutableArray alloc] initWithCapacity:1];
    for (RssFeedObject *rssObj in _feedModel.dataArr)
    {




    RssTableItem
    *itemObj = [RssTableItem itemWithRssFeedObj:rssObj];

    [items addObject:itemObj];
    }

    self.items
    = items;
    TT_RELEASE_SAFELY(items);
    }

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


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


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

    - (Class)tableView:(UITableView*)tableView cellClassForObject:(id) object {

    if ([object isKindOfClass:[RssTableItem class]]) {
    return [RssTableItemCell class];
    }
    else {
    return [super tableView:tableView cellClassForObject:object];
    }
    }

    - (void)tableView:(UITableView*)tableView prepareCell:(UITableViewCell*)cell
    forRowAtIndexPath:(NSIndexPath
    *)indexPath {
    cell.accessoryType
    = UITableViewCellAccessoryDetailDisclosureButton;
    }


    @end

    我们再看下model是怎么工作的.因为我们需要请求数据,所以生成TTURLRequestModel的子类,在requestDidFinishLoad:方法解析数据,获得的结果会返回给datasource

    RssFeedModel
    #import <Foundation/Foundation.h>


    @interface RssFeedModel : TTURLRequestModel {

    NSString
    *_queryStr;

    NSMutableArray
    *_dataArr;
    }

    @property (nonatomic, copy) NSString
    *queryStr;
    @property (nonatomic, retain) NSMutableArray
    *dataArr;

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

    #import "RssFeedModel.h"
    #import "RssFeedObject.h"

    #define kID @"id"
    #define kImArtist @"im:artist"
    #define kLink @"link"
    #define kCategory @"category"
    #define kTitle @"title"
    #define kImContentType @"im:contentType"
    #define kRights @"rights"
    #define kImPrice @"im:price"
    #define kImImage @"im:image"
    #define kImReleaseDate @"im:releaseDate"
    #define kImItemCount @"im:itemCount"
    #define kImName @"im:name"
    #define kUpdated @"updated"
    #define kContent @"content"

    #define KeysArray nil


    #define KEntityName @"___Entity_Name___"
    #define kEntityType @"___Entity_Type___"
    #define kEntityValue @"___Entity_Value___"

    #define kHeight @"height"
    #define kImageHeight @"60"

    #define kRSSFeed @"http://itunes.apple.com/us/rss/topalbums/limit=10/explicit=true/xml"

    @implementation RssFeedModel
    @synthesize queryStr = _queryStr, dataArr = _dataArr;

    - (id)initWithSearchQuery:(NSString*)searchQuery
    {
    if (self = [super init])
    {
    self.queryStr
    = searchQuery?searchQuery:@"";
    _dataArr
    = [[NSMutableArray alloc] initWithCapacity:1];
    }
    return self;
    }

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

    - (void)load:(TTURLRequestCachePolicy)cachePolicy more:(BOOL)more
    {
    NSString
    * url = [NSString stringWithFormat:@"%@",kRSSFeed];

    TTURLRequest
    * request = [TTURLRequest
    requestWithURL: url
    delegate: self];

    request.cachePolicy
    = cachePolicy;
    request.cacheExpirationAge
    = TT_CACHE_EXPIRATION_AGE_NEVER;
    TTURLXMLResponse
    * response = [[TTURLXMLResponse alloc] init];
    response.isRssFeed
    = YES;
    request.response
    = response;
    TT_RELEASE_SAFELY(response);

    [request send];
    }




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

    // [NSArray arrayWithObjects:kID,kImArtist,kLink,kCategory,kTitle,kImContentType
    TTURLXMLResponse *xmlResponse = request.response;

    NSDictionary
    *feed = xmlResponse.rootObject;

    NSArray
    *allKey = [feed allKeys];

    NSMutableArray
    *mArr = [NSMutableArray arrayWithCapacity:1];
    for (NSString *str in allKey)
    {
    NSLog(
    @"%@\n",str);
    [mArr addObject:[feed objectForKey:str]];
    }
    NSArray
    *entry = [feed objectForKey:@"entry"];//rss feed:每个是一个dictionary代表一行



    for(NSDictionary *item in entry)
    {
    RssFeedObject
    *obj = [[RssFeedObject alloc] init];

    for( NSString *str in [item allKeys])
    {
    id attr = [item valueForKey:str];
    if ([attr isKindOfClass:[NSDictionary class]])
    {

    NSArray
    *attrKeys = [attr allKeys];

    NSString
    *entityName = [(NSDictionary *)attr valueForKey:KEntityName];
    if ([entityName isEqualToString:kID])
    {
    obj.readMore
    = [(NSDictionary *)attr valueForKey:kEntityValue];

    }

    else if ([entityName isEqualToString:kImArtist])
    {
    obj.artist
    = [(NSDictionary *)attr valueForKey:kEntityValue];

    }

    else if ([entityName isEqualToString:kCategory])
    {
    obj.genre
    = [(NSDictionary *)attr valueForKey:@"label"];

    }

    else if ([entityName isEqualToString:kTitle])
    {
    obj.header
    = [(NSDictionary *)attr valueForKey:kEntityValue];

    }

    else if ([entityName isEqualToString:kRights])
    {
    obj.copyRight
    = [(NSDictionary *)attr valueForKey:kEntityValue];

    }

    else if ([entityName isEqualToString:kImPrice])
    {
    obj.price
    = [(NSDictionary *)attr valueForKey:kEntityValue];

    }


    else if ([entityName isEqualToString:kImReleaseDate])
    {
    obj.releaseDate
    = [(NSDictionary *)attr valueForKey:kEntityValue];

    }


    else if ([entityName isEqualToString:kImItemCount])
    {
    obj.itemCount
    = [(NSDictionary *)attr valueForKey:kEntityValue];

    }


    else if ([entityName isEqualToString:kImName])
    {
    obj.title
    = [(NSDictionary *)attr valueForKey:kEntityValue];

    }


    else if ([entityName isEqualToString:kUpdated])
    {
    obj.updateDate
    = [(NSDictionary *)attr valueForKey:kEntityValue];

    }
    else {

    }

    }

    else if ([attr isKindOfClass:[NSArray class]])
    {
    for (NSDictionary *imagDic in attr)
    {
    NSString
    *height = [imagDic valueForKey:kHeight];
    if ([height isEqualToString:kImageHeight])
    {
    obj.imageLink
    = [imagDic valueForKey:kEntityValue];
    }
    }
    }

    }

    [self.dataArr addObject:obj];
    TT_RELEASE_SAFELY(obj);
    }

    NSDictionary
    *item = [entry objectAtIndex:0];

    NSArray
    *itemKeys = [item allKeys];
    NSMutableArray
    *itemContent = [NSMutableArray arrayWithCapacity:1];
    for(NSString *str in itemKeys)
    {
    [itemContent addObject:[item objectForKey:str]];
    NSLog(
    @"%@:%@\n",str,[item objectForKey:str]);
    }



    NSLog(
    @"%@",feed);

    [super requestDidFinishLoad:request];
    //important
    }
    @end

    tableItemCell就是自定义的cell,tableItem是tableviewcell所代表的object,在cell中需要将object与view(就是cell)联系起来.在这里我们也可以体会到MVC在iOS中真的是无处不在.

    RssTableItem
    #import <Foundation/Foundation.h>

    @class RssFeedObject;

    @interface RssTableItem : TTTableItem
    {
    NSString
    *_artist;
    NSString
    *_title;
    NSString
    *_link;
    NSString
    *_imageName;
    }

    @property (nonatomic, copy) NSString
    *artist;
    @property (nonatomic, copy) NSString
    *title;
    @property (nonatomic, copy) NSString
    *link;
    @property (nonatomic, copy) NSString
    *imageName;

    +(id)itemWithRssFeedObj:(RssFeedObject *)obj;

    -(id)initWithRssFeedObj:(RssFeedObject *)obj;
    @end

    #import "RssTableItem.h"
    #import "RssFeedObject.h"

    @implementation RssTableItem
    @synthesize artist = _artist, title = _title,link = _link,imageName = _imageName;

    - (id)init
    {
    if (self = [super init])
    {
    _artist
    = nil;
    _title
    = nil;
    _link
    = nil;
    _imageName
    = nil;
    }
    return self;
    }

    +(id)itemWithRssFeedObj:(RssFeedObject *)obj
    {
    RssTableItem
    *item = [[[RssTableItem alloc] init] autorelease];
    item.artist
    = obj.artist;
    item.title
    = obj.title;
    item.link
    = obj.readMore;
    item.imageName
    = obj.imageLink;

    return item;

    }

    -(id)initWithRssFeedObj:(RssFeedObject *)obj
    {
    if (self = [[RssTableItem alloc] init])
    {
    self.artist
    = obj.artist;
    self.title
    = obj.title;
    self.link
    = obj.readMore;
    self.imageName
    = obj.imageLink;
    }

    return self;
    }

    - (void)dealloc
    {
    TT_RELEASE_SAFELY(_artist);
    TT_RELEASE_SAFELY(_title);
    TT_RELEASE_SAFELY(_title);
    TT_RELEASE_SAFELY(_imageName);
    [super dealloc];
    }

    @end
    RssTableItemCell
    #import <Foundation/Foundation.h>


    @interface RssTableItemCell : TTTableViewCell {
    UILabel
    *_artistLab;
    UILabel
    *_titleLab;
    TTImageView
    *_myImageView;
    }

    @end


    #import "RssTableItemCell.h"
    #import "RssTableItem.h"

    @implementation RssTableItemCell
    + (CGFloat)tableView:(UITableView*)tableView rowHeightForObject:(id)object
    {
    return 60;
    }

    - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)identifier
    {
    if (self = [super initWithStyle:style reuseIdentifier:identifier])
    {
    _myImageView
    = [[TTImageView alloc] initWithFrame:CGRectMake(5, 0, 60, 60)];
    [self.contentView addSubview:_myImageView];

    _artistLab
    = [[UILabel alloc] initWithFrame:CGRectMake(70, 10, 200, 10)];
    _artistLab.textColor
    = [UIColor grayColor];
    _artistLab.backgroundColor
    = [UIColor clearColor];
    [self.contentView addSubview:_artistLab];


    _titleLab
    = [[UILabel alloc] initWithFrame:CGRectMake(70, 30, 200, 20)];
    _titleLab.textColor
    = [UIColor grayColor];
    _titleLab.backgroundColor
    = [UIColor clearColor];
    [self.contentView addSubview:_titleLab];

    }
    return self;
    }

    - (void)dealloc
    {
    TT_RELEASE_SAFELY(_artistLab);
    TT_RELEASE_SAFELY(_myImageView);
    TT_RELEASE_SAFELY(_titleLab);
    [super dealloc];
    }


    - (void)layoutSubviews
    {
    [super layoutSubviews];

    }

    - (id)object
    {
    return self;;
    }

    - (void)setObject:(id)obj
    {
    if (self != obj)
    {
    [super setObject:obj];
    RssTableItem
    *item = obj;

    _myImageView.urlPath
    = item.imageName;
    _artistLab.text
    = item.artist;
    _titleLab.text
    = item.title;
    }
    }


    @end

    最后是一个解析数据的对象模型RssFeedObject.

    RssFeedObject
    #import <Foundation/Foundation.h>


    @interface RssFeedObject : NSObject {
    NSString
    *_header;
    NSString
    *_title;
    NSString
    *_artist;
    NSString
    *_genre;
    NSString
    *_price;
    NSString
    *_releaseDate;
    NSString
    *_copyRight;
    NSString
    *_readMore;

    NSString
    *_itemCount;
    NSString
    *_imageLink;
    NSString
    *_updateDate;
    }

    @property (nonatomic, copy) NSString
    *header,*title,*artist,*genre;
    @property (nonatomic, copy) NSString
    *price,*releaseDate,*copyRight,*readMore;
    @property (nonatomic, copy) NSString
    *itemCount,*imageLink,*updateDate;


    @end

    #import "RssFeedObject.h"


    @implementation RssFeedObject
    @synthesize header=_header,title=_title,artist=_artist,genre=_genre;

    @synthesize price=_price,releaseDate=_releaseDate,copyRight=_copyRight,readMore=_readMore;

    @synthesize itemCount = _itemCount,imageLink = _imageLink,updateDate = _updateDate;
    - (void)dealloc
    {
    TT_RELEASE_SAFELY(_header);
    TT_RELEASE_SAFELY(_title);
    TT_RELEASE_SAFELY(_artist);
    TT_RELEASE_SAFELY(_genre);
    TT_RELEASE_SAFELY(_price);
    TT_RELEASE_SAFELY(_releaseDate);
    TT_RELEASE_SAFELY(_copyRight);
    TT_RELEASE_SAFELY(_readMore);

    TT_RELEASE_SAFELY(_itemCount);
    TT_RELEASE_SAFELY(_imageLink);
    TT_RELEASE_SAFELY(_updateDate);
    [super dealloc];
    }
    @end

    至此我们的工程就完成了.程序的大致流程如图3所示,具体的代码细节都是很容易理解的.如果有写的不明白或者错误的地方请多多指正.

    谢谢.

    ps:有谁知道mac下有没有啥好的博客客户端啊,不然家里都打不开,只能到公司里抽时间写

    Top
  • 相关阅读:
    椒盐噪声加噪的实现原理
    椒盐噪声加噪的实现原理
    TensorFlow 实现深度神经网络 —— Denoising Autoencoder
    TensorFlow 实现深度神经网络 —— Denoising Autoencoder
    TensorFlow 辨异 —— tf.add(a, b) 与 a+b(tf.assign 与 =)、tf.nn.bias_add 与 tf.add
    概念的理解 —— 奇点(singularity point)、第一性原理(first principle)
    概念的理解 —— 奇点(singularity point)、第一性原理(first principle)
    TensorFlow 学习(十四)—— contrib
    TensorFlow 学习(十三)—— tf.app.flags
    tensorflow 的使用流程
  • 原文地址:https://www.cnblogs.com/scorpiozj/p/2091259.html
Copyright © 2011-2022 走看看