我从NSXMLParser将数据加载到我的UITableView中。 这一切都运行正常但我想要实现的是App加载XML数据时的一些活动,所以对用户来说这一切都更加友好。 我发现的一些样本仍然让我感到困惑,因为我没有采用与XMLParser实现相同的方式。
我在这里提供了我的数据,请提供一些关于如何将其放入我的代码中的代码示例。
XMLParser.h:
#import <UIKit/UIKit.h>
@class DAFAppDelegate, Stage, Month;
@interface XMLParser : NSObject <NSXMLParserDelegate>
{
NSMutableString *currentElementValue;
DAFAppDelegate *appDelegate;
Stage *aStage;
Month *aMonth;
}
- (XMLParser *) initXMLParser;
+ (NSDate *)dateFromString:(NSString *)dateString;
+ (NSString *)stringFromDate:(NSDate *)stringDate;
@end
XMLParser.m:
#import "XMLParser.h"
#import "DAFAppDelegate.h"
#import "Stage.h"
#import "Month.h"
@implementation XMLParser
- (XMLParser *) initXMLParser
{
[super init];
appDelegate = (DAFAppDelegate *)[[UIApplication sharedApplication] delegate];
return self;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
if([elementName isEqualToString:@"Stages"])
{
//Initialize the array.
appDelegate.stages = [[NSMutableArray alloc] init];
}
if([elementName isEqualToString:@"Month"])
{
//Initialize the Month.
aMonth = [[Month alloc] init];
aMonth.stagesPerMonth = [[NSMutableArray alloc] init];
//Extract the attribute here.
aMonth.name = [attributeDict valueForKey:@"name"];
aMonth.monthID = [[attributeDict objectForKey:@"id"] integerValue];
NSLog(@"Reading Month id value :%i", aMonth.monthID);
NSLog(@"Reading Month name value :%@", aMonth.name);
}
if([elementName isEqualToString:@"Stage"])
{
//Initialize the Stage.
aStage = [[Stage alloc] init];
//Extract the attribute here.
aStage.stageID = [[attributeDict objectForKey:@"id"] integerValue];
NSLog(@"Reading id value :%i", aStage.stageID);
}
NSLog(@"Processing Element: %@", elementName);
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if(!currentElementValue)
{
currentElementValue = [[NSMutableString alloc] initWithString:string];
}
else
{
[currentElementValue appendString:string];
}
NSLog(@"Processing Value: %@", currentElementValue);
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
NSDate* date = [NSDate date];
NSDateFormatter* nsformatter = [[[NSDateFormatter alloc] init] autorelease];
[nsformatter setDateFormat:@"yyyy-MM-dd"];
NSDate* stageDate = [XMLParser dateFromString:aStage.end];
if([elementName isEqualToString:@"Stages"])
{
return;
}
if([elementName isEqualToString:@"Month"])
{
if (!aMonth.stagesPerMonth || aMonth.stagesPerMonth.count)
{
[appDelegate.stages addObject:aMonth];
}
[aMonth release];
aMonth = nil;
}
if([elementName isEqualToString:@"Stage"])
{
NSTimeInterval interval = [date timeIntervalSinceDate:stageDate];
if (interval < 0)
{
[aMonth.stagesPerMonth addObject:aStage];
}
[aStage release];
aStage = nil;
}
else
{
[aStage setValue:currentElementValue forKey:elementName];
[currentElementValue release];
currentElementValue = nil;
}
}
-(void) parserDidStartDocument:(NSXMLParser *)parser
{
NSLog(@"parserDidStartDocument");
}
-(void) parserDidEndDocument: (NSXMLParser *)parser
{
NSLog(@"parserDidEndDocument");
}
+ (NSDate *)dateFromString:(NSString *)dateString
{
NSDateFormatter *nsDateFormatter = [[NSDateFormatter alloc] init];
[nsDateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm"];
NSDate *date = [nsDateFormatter dateFromString:dateString];
return date;
[nsDateFormatter release];
}
+ (NSString *)stringFromDate:(NSDate *)stringDate
{
NSDateFormatter *stringDateFormatter = [[NSDateFormatter alloc] init];
NSLocale *nlLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"nl_NL"];
[stringDateFormatter setLocale:nlLocale];
[stringDateFormatter setDateFormat:@"EEE', 'dd MMMM yyyy HH:mma"];
NSString *dateString = [stringDateFormatter stringFromDate:stringDate];
return dateString;
[stringDateFormatter release];
}
- (void) dealloc
{
[aStage release];
[aMonth release];
[currentElementValue release];
[super dealloc];
}
@end
DAFAppDelegate.h:
@class RootViewController;
@interface DAFAppDelegate : NSObject <UIApplicationDelegate>
{
UIWindow *window;
UINavigationController *navigationController;
IBOutlet UITabBarController *rootTabController;
RootViewController *rootViewController;
NSMutableArray *stages;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UITabBarController *rootTabController;
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
@property (nonatomic, retain) IBOutlet RootViewController *rootViewController;
@property (nonatomic, retain) NSMutableArray *stages;
+ (void) showAlert;
@end
DAFAppDelegate.m:
#import "DAFAppDelegate.h"
#import "RootViewController.h"
#import "XMLParser.h"
@implementation DAFAppDelegate
@synthesize window;
@synthesize navigationController;
@synthesize rootViewController;
@synthesize rootTabController;
@synthesize stages;
+ (void) showAlert
{
UIAlertView *av = [[[UIAlertView alloc] initWithTitle:@"No Connection" message:@"Could not retrieve data" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
[av show];
}
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
NSURL *url = [[NSURL alloc] initWithString:@"http://web.me.com/ijar/Stages.xml"];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
//Initialize the delegate.
XMLParser *parser = [[XMLParser alloc] initXMLParser];
//Set delegate
[xmlParser setDelegate:parser];
//Start parsing the XML file.
BOOL success = [xmlParser parse];
if(success)
{
NSLog(@"No Errors");
}
else
{
[DAFAppDelegate showAlert];
NSLog(@"Error Error Error!!!");
}
[window addSubview:[rootTabController view]];
[window makeKeyAndVisible];
}
- (void)dealloc
{
[navigationController release];
[rootViewController release];
[rootTabController release];
[window release];
[stages release];
[super dealloc];
}
@end
RootViewController.h:
@class DAFAppDelegate;
@interface RootViewController : UITableViewController
{
DAFAppDelegate *appDelegate;
}
@end
RootViewController.m:
#import "RootViewController.h"
#import "DAFAppDelegate.h"
#import "DetailViewController.h"
#import "XMLParser.h"
#import "Stage.h"
#import "Month.h"
#import "AgendaCustomCell.h"
@implementation RootViewController
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
appDelegate = (DAFAppDelegate *)[[UIApplication sharedApplication] delegate];
self.title = NSLocalizedString(@"Agenda", @"Master view navigation title");
UIImageView *image=[[UIImageView alloc]initWithFrame:CGRectMake(0,0,45,45)] ;
[image setImage:[UIImage imageNamed:@"topBarIcon.png"]];
[self.navigationController.navigationBar.topItem setTitleView:image];
self.tableView.backgroundColor = [UIColor clearColor];
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [appDelegate.stages count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
Month *aMonth = [appDelegate.stages objectAtIndex:section];
return aMonth.name;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
Month *aMonth = [appDelegate.stages objectAtIndex:section];
return [aMonth.stagesPerMonth count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"AgendaCustomCell";
AgendaCustomCell *cell = (AgendaCustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
NSArray *topLevelObject = [[NSBundle mainBundle] loadNibNamed:@"AgendaCustomCell" owner:nil options:nil];
for (id currentObject in topLevelObject)
{
if ([currentObject isKindOfClass:[UITableViewCell class]])
{
cell = (AgendaCustomCell *)currentObject;
break;
}
}
}
Month *aMonth = [appDelegate.stages objectAtIndex:indexPath.section];
Stage *aStage = [aMonth.stagesPerMonth objectAtIndex:indexPath.row];
NSString *startDate = [XMLParser stringFromDate:[XMLParser dateFromString:aStage.start]];
NSString *endDate = [XMLParser stringFromDate:[XMLParser dateFromString:aStage.end]];
int endDateLength = endDate.length;
NSString *dateTitle = [NSString stringWithFormat:@"%@ - %@", startDate, [endDate substringFromIndex:endDateLength -7]];
cell.titleLabel.text = aStage.title;
cell.dateLabel.text = dateTitle;
cell.nameLabel.text = aStage.teacher;
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 60;
}
#pragma mark -
#pragma mark Table view selection
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//When a row is selected, create the detail view controller and set its detail item to the item associated with the selected row.
DetailViewController *detailViewController = [[DetailViewController alloc] initWithStyle:UITableViewStyleGrouped];
Month *aMonth = [appDelegate.stages objectAtIndex:indexPath.section];
detailViewController.stage = [aMonth.stagesPerMonth objectAtIndex:indexPath.row];
// Push the detail view controller.
[[self navigationController] pushViewController:detailViewController animated:YES];
[detailViewController release];
}
#pragma mark -
#pragma mark Memory management
- (void)dealloc
{
[appDelegate release];
[super dealloc];
}
@end
答案 0 :(得分:3)
如果您想在状态栏调用中使用标准活动指示器:
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
在你调用解析器之前。
然后,一旦解析器完成(didEndDocument方法),就调用:
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
答案 1 :(得分:0)
我不打算为你编写代码,但这里有一些你可以采取的步骤。 1.要获得更好的UX,请在开始xml解析之前将RootViewController.view添加到窗口。 2.在RootViewController:viewDidLoad方法中,创建并显示UIActivityIndicatorView(“微调器”)。 3.解析完成后,在RootViewController上调用一个方法,它执行以下三项操作: a)隐藏旋转器 b)加载tableView的数据源(aMonth.stagesPerMonth) c)tableView [reloadData];
祝你好运。 -Mike