问候,人们。
我第一次潜入Objective-C。它正在踢我的C#屁股,但是(嘿)我想我终于开始“得到”一些概念了。
我正在编写一个连接到Web服务的iPhone应用程序,以XML格式提取数据,解析数据并将其呈现为UITableView。单击tableview中的单元格可加载详细信息视图,依此类推。
我遇到了一些概念问题。在C#中,大多数控件都有一个显示标签和一个值。这样可以很容易地将事件(我沉迷的另一件事)附加到单元格或条目,并键入值以进一步查找。
我遇到的问题是UITableView虽然是为详细视图构建的,但它似乎没有值属性或任何我可以智能地键入来将标识符传递给详细视图并填充它。
目前我正在通过将我的XML提要解析为NSMutableArray来处理这个问题,该NSMutableArray包含有关特定条目的所有数据。我根据该数组中的一个特定字段填充UITableView。然后我使用objectAtIndex:indexPath.row将任何标识符等传递给详细信息视图。
我可以像这样继续前进并让它发挥作用,但整个事情感觉就像是一团糟,并且它会成为一个维持/扩展的怪物。所以,有了这个说...请帮助我!我要发布很多我的代码,这样你就可以看到我接近这个有多糟糕了:))
桌面视图控制器我非常糟糕:
#import "InvoicesTableViewController.h"
#import "Wrapper.h"
#import "InvoiceDetailViewController.h"
@implementation InvoicesTableViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[listOfItems release];
[restAPI release];
[parameters release];
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - Wrapper
- (void)wrapper:(Wrapper *)wrapper didRetrieveData:(NSData *)data
{
NSData *result = [[restAPI responseAsText] dataUsingEncoding:NSUTF8StringEncoding];
if (result != nil)
{
NSXMLParser *parser = [[[NSXMLParser alloc] initWithData:result] autorelease];
parser.delegate = self;
[parser parse];
}
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
#pragma mark - Parser
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
if(OneInvoice == nil)
{
OneInvoice = [[NSMutableArray alloc] init];
}
if ([elementName isEqualToString:@"invoice"])
{
[OneInvoice addObject:[attributeDict valueForKey:@"uri"]];
[OneInvoice addObject:[attributeDict valueForKey:@"total"]];
[OneInvoice addObject:[attributeDict valueForKey:@"total_due"]];
[OneInvoice addObject:[attributeDict valueForKey:@"status"]];
}
if ([elementName isEqualToString:@"client"])
{
[OneInvoice addObject:[attributeDict valueForKey:@"name"]];
[listOfItems addObject:[[NSMutableArray alloc] initWithArray:OneInvoice copyItems:YES]];
[OneInvoice release];
OneInvoice = nil;
[self.tableView reloadData];
}
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
listOfItems = [[NSMutableArray alloc] init];
//Set the title
self.navigationItem.title = @"Invoices";
if(restAPI == nil) {
restAPI = [[Wrapper alloc] init];
}
restAPI.delegate = self;
parameters = nil;
restAPI.mimeType = @"application/vnd.site+xml";
url = [NSURL URLWithString: @"https://user:pass@site.com/invoices/?status=all"];
[restAPI sendRequestTo:url usingVerb: @"GET" withParameters: parameters];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [listOfItems count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Setup the cell
NSString *cellValue = [NSString stringWithFormat:@"%@ - %@", [[listOfItems objectAtIndex:indexPath.row] objectAtIndex:4],[[listOfItems objectAtIndex:indexPath.row] objectAtIndex:1]];
cell.textLabel.text = cellValue;
return cell;
}
- (UITableViewCellAccessoryType)tableView:(UITableView *)tableView accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath {
//return UITableViewCellAccessoryDetailDisclosureButton;
return UITableViewCellAccessoryDetailDisclosureButton;
//return UITableViewCellAccessoryDisclosureIndicator;
}
/*
// 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;
}
*/
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *invoiceURL = [[listOfItems objectAtIndex:indexPath.row] objectAtIndex:0];
InvoiceDetailViewController *dvController = [[InvoiceDetailViewController alloc] initWithNibName:@"InvoiceDetailViewController" bundle:[NSBundle mainBundle]];
dvController.invoiceURL = invoiceURL;
[self.navigationController pushViewController:dvController animated:YES];
[dvController release];
dvController = nil;
}
@end
请不要犹豫,嘲笑我的表格。我对C / C ++缺乏经验,特别是Objective-C。我昨晚一起蠢蠢欲动,只是为了让一些工作,我可以建立起来。
万分感谢 克利夫顿
答案 0 :(得分:1)
Cocoa使用模型 - 视图 - 控制器范例。在您的情况下,模型是NSMutableArray,控制器是表视图控制器,视图是UITableView。 表格单元格不包含任何数据。单击一个单元格时控制器将收到通知,并将找出相应的数据(如您所做的那样),然后调用另一个控制器,更新模型或更新视图。
答案 1 :(得分:1)
您的代码看起来正确。我不知道你担心的“混乱”是什么。您有一个数据源,数据源显示在表中。用户从表中选择一行,将数据引用传递给详细视图。如果你想要超级数据建模 - 功夫你可以查看核心数据,你可以连接一个TableView来自动显示核心数据实体。