View Controller Nav 中的 iOS Refresh 按钮:单击时重新加载从解析的 JSON 创建的所有 tableViewCell
Posted
技术标签:
【中文标题】View Controller Nav 中的 iOS Refresh 按钮:单击时重新加载从解析的 JSON 创建的所有 tableViewCell【英文标题】:iOS Refresh button in View Controller Nav: reloading all tableViewCells created from parsed JSON when clicked 【发布时间】:2011-12-22 18:26:18 【问题描述】:我有一个相当重要的概念性问题,很多人都问过,但没有现成的明确答案可以通过搜索找到。
我的应用程序很简单:几行 TableViewCells 填充了来自解析的 JSON 提要的数据。单击单元格时,该单元格的信息将传递给 SecondViewController 并显示。 JSON 提要也存储到 .plist 中,如果互联网不可用,则从 .plist 填充 TableViewCells。
这一切都很好。
但是,我需要的最后一件事是我的 FirstViewController 顶部的刷新按钮来刷新 JSON 提要,以及表中的所有单元格以及来自新变量的新数据。但是,我在实现此功能时遇到了问题:
我的原始 JSON 调用和填充单元格的变量位于 ViewDidLoad 方法中。当视图加载时,这些变量被“设置”并且不会刷新。此外,我可以将 JSON 调用和变量移动到 viewWillLoad 中——每次单击单元格后都会刷新表格,然后单击“返回”到 firstViewController——这将成功更新 JSON 和单元格,但它确实会影响当返回 MainViewController 时,速度并使视图控制器“暂停”,这使得调用我的原始 JSON 并在 viewWillLoad 中设置我的变量成为一个不可行的选项。
我在 ViewDidLoad 中创建了一个重新加载按钮,该按钮链接到 IBAction 方法“刷新”:
在 ViewDidLoad 中以编程方式创建按钮:
// Reload issues button
UIBarButtonItem *button = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh
target:self
action:@selector(refresh:)];
self.navigationItem.rightBarButtonItem = button;
[button release];
它链接到的操作方法:
- (IBAction)refresh:(id)sender
myRawJson = [[NSString alloc] initWithContentsOfURL:[NSURL
URLWithString:@"http://www.yoursite.com/json.JSON"]
encoding:NSUTF8StringEncoding
error:nil];
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSDictionary * myParsedJson = [parser objectWithString:myRawJson error:NULL];
// New updated dictionary built from refreshed JSON
allLetterContents = [myParsedJson objectForKey:@"nodes"];
// Log the new refreshed JSON
NSLog(@"You clicked refresh. Your new JSON is %@", myRawJson);
//Maybe use the notification center?? But don't know how to implement.
//[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(refreshView:)
name:@"refreshView" object:nil];
//[[NSNotificationCenter defaultCenter] postNotificationName:@"refreshView"
object:nil];
[self.tableView reloadRowsAtIndexPaths:[self.tableView indexPathsForVisibleRows]
withRowAnimation:UITableViewRowAnimationNone];
[myRawJson release];
在上面的代码中,您可以看到每次单击按钮时我都会重新调用 JSON,并使用新的 JSON 将消息记录到控制台。这是有效的。我什至重新构建了一个成功添加新内容的字典。
我的问题是:如何让 tableViewCells 也用这些新数据“刷新”?我可以让按钮重新加载整个视图控制器 - 所以它会再次调用 ViewDidLoad 吗?我是否需要重新考虑我的应用程序结构,或者将我的原始变量移出 viewDidLoad?
我一直在阅读 NSNotificationCenter 上的一些帖子,但由于我对 ios 开发还很陌生。
谢谢~
更新:
它仍然没有更新。这是我的完整刷新按钮代码,带有 [self.tableView reloadData];在我的 IBAction 结束时调用。
- (IBAction)refresh:(id)sender
[DSBezelActivityView newActivityViewForView:
self.navigationController.navigationBar.superview
withLabel:@"Loading Feed..." width:160];
myRawJson = [[NSString alloc] initWithContentsOfURL:[NSURL
URLWithString:@"http://site.com/mobile.JSON"]
encoding:NSUTF8StringEncoding
error:nil];
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSDictionary * myParsedJson = [parser objectWithString:myRawJson error:NULL];
allLetterContents = [myParsedJson objectForKey:@"nodes"];
BOOL isEmpty = ([myParsedJson count] == 0);
if (isEmpty)
NSString *refreshErrorMessage = [NSString
stringWithFormat:@"An internet or network connection is required."];
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:@"Alert"
message: refreshErrorMessage
delegate:self
cancelButtonTitle:@"Close"
otherButtonTitles:nil];
[alert show];
[alert release];
allLetterContents = [NSMutableDictionary
dictionaryWithContentsOfFile:[self saveFilePath]];
//NSLog(@"allLetterContents from file: %@", allLetterContents);
else
NSLog(@"Your new allLetterContents is %@", allLetterContents);
// Fast enumeration through the allLetterContents NSMutableDictionary
for (NSMutableDictionary * key in allLetterContents)
NSDictionary *node = [key objectForKey:@"node"];
NSMutableString *contentTitle = [node objectForKey:@"title"];
NSMutableString *contentNid = [node objectForKey:@"nid"];
NSMutableString *contentBody = [node objectForKey:@"body"];
// Add each Title and Nid to specific arrays
//[self.contentTitleArray addObject:contentTitle];
[self.contentTitleArray addObject:[[contentTitle
stringByReplacingOccurrencesOfString:@"&"
withString:@"&"] mutableCopy]];
[self.contentNidArray addObject:contentNid];
[self.contentBodyArray addObject:contentBody];
[self.tableView reloadData];
[DSBezelActivityView removeViewAnimated:YES];
[myRawJson release];
我在 cellForRowAtIndexPath 处配置单元格(更新:已发布整个方法):
- (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] autorelease];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
// Configure the cell.
cell.textLabel.text = [self.contentTitleArray objectAtIndex: [indexPath row]];
cell.detailTextLabel.text = [self.contentNidArray objectAtIndex: [indexPath row]];
return cell;
在 didSelectRowAtIndexPath 上设置它:
self.detailViewController.currentNodeTitle = [contentTitleArray
objectAtIndex:indexPath.row];
self.detailViewController.currentNodeNid= [contentNidArray
objectAtIndex:indexPath.row];
self.detailViewController.currentNodeBody = [contentBodyArray
objectAtIndex:indexPath.row];
因此,当单击我的刷新按钮时,表格应该* 使用新的 json 刷新,但不会。我错过了一步吗?
此外,这可能并不重要,但我正在更改每隔一行的颜色:
// Customize the appearance of table view cells.
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
if (indexPath.row % 2)
[cell setBackgroundColor:[UIColor colorWithRed:221.0/255.0 green:238.0/255.0 blue:255.0/255.0 alpha:1]];
cell.textLabel.textColor = [UIColor colorWithRed:2.0/255.0 green:41.0/255.0 blue:117.0/255.0 alpha:1];
cell.detailTextLabel.textColor = [UIColor colorWithRed:2.0/255.0 green:41.0/255.0 blue:117.0/255.0 alpha:1];
else [cell setBackgroundColor:[UIColor clearColor]];
更新
【问题讨论】:
我怀疑cellForRowAtIndexPath:
有问题,您只粘贴了一小部分。
@Krizz - 我添加了整个 cellForRowAtIndexPath。我没有发布整个方法,因为除了我添加的内容之外,它是完全标准的。 - 谢谢
您是否使用调试器验证了[self.tableView reloadData];
已到达并且tableView
不为零?
目前我的视图中有包含内容的单元格,所以我认为这意味着 tableView 有单元格,因此不为空。下面记录大于 0 的 NSLog: if (self.tableView > 0) [self.tableView reloadData]; NSLog(@"你的tableview大于0"); - 所以是的,我认为它不是零。我注意到的另一件事是,即使我的 IBAction 使用代码连接到刷新方法,该方法旁边的圆圈仍然显示为未链接。这一定是在您使用代码而不是 GUI 创建按钮时引起的。 (附截图)。
【参考方案1】:
你需要调用reload方法。
[self.tableView reloadData];
这将触发dataSource
和delegate
事件并刷新UITableView
。
您可以在UITableView Class Reference找到更多信息:
调用此方法可重新加载用于构建表格的所有数据,包括单元格、节页眉和页脚、索引数组等。为了提高效率,表格视图只重新显示那些可见的行。
【讨论】:
嗯,这是许多其他帖子所说的,但是当我添加 [self.tableView reloadData];到 - (IBAction)refresh:(id)sender 的末尾,它没有任何效果。还有其他想法吗?或者我只是在错误的地方调用它? 我已更新我的帖子以包含我的 IBAction 代码和更多信息。也许我错过了一些代码?我可以通过运行应用程序验证 JSON 是否已更改,然后更新 JSON 源,当我单击“刷新”按钮时,我的 NSLog 显示刷新按钮输出新内容,但单元格不更新。以上是关于View Controller Nav 中的 iOS Refresh 按钮:单击时重新加载从解析的 JSON 创建的所有 tableViewCell的主要内容,如果未能解决你的问题,请参考以下文章
如何在没有导航栏的 View Controller 内使用 Nav 推送 UIViewController
将数据从 Table View Cell 传递到 IOS 中的 View Controller
Google Sign In 调用 App Delegate 中的方法后关闭 View Controller (iOS / Swift)