【问题标题】:Why won't my UITableViewCell deselect and update its text?为什么我的 UITableViewCell 不会取消选择并更新其文本?
【发布时间】:2011-01-04 16:44:18
【问题描述】:

我有一个 UITableView,其中包含一个故事列表和一个底部的单元格,用于加载更多故事。我正在尝试取消选择“更多故事...”单元格并将其文本更改为“正在加载...”。我已经在整个互联网和 stackoverflow 上进行了搜索,但我无法弄清楚为什么我的代码不能正常工作。现在,当单击“更多故事...”单元格时,它会保持选中状态并且永远不会更改其文本。

对于那些询问的人,moreStories 会在表格视图的底部添加 25 个新故事。

原代码:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic
int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
if (storyIndex == [stories count]) {
    UITableViewCell *moreCell = [tableView dequeueReusableCellWithIdentifier:@"more"];
    if (moreCell == nil) {
        moreCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"more"] autorelease];
    } // Set up the cell
    moreCell.textLabel.text = @"Loading...";

    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    [self moreStories];
} else { 
    NSLog(@"%@",[[stories objectAtIndex: storyIndex] objectForKey: @"link"]);
    webViewController *webController;
    webController = [[webViewController alloc] initWithURLPassed:[[stories objectAtIndex: storyIndex] objectForKey: @"link"]];
    [self.navigationController pushViewController:webController animated:YES];
    [webController release];
    webController =nil;
    self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStylePlain target:nil action:nil];
}
}

已更新,但仍无法正常工作。现在它最终取消选择单元格并将文本更改为“正在加载...”,但只有在 moreStories 完成下载所有故事之后。显然,我希望在下载故事时文本为“正在加载...” 1/4/10 ~9pm

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic
int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
if (storyIndex == [stories count]) {
    UITableViewCell *moreCell = [tableView cellForRowAtIndexPath:indexPath];
    moreCell.textLabel.text = @"Loading...";
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    NSArray *arr = [[NSArray alloc] initWithObjects:indexPath,nil];
    [tableView beginUpdates];
    [tableView reloadRowsAtIndexPaths:arr withRowAnimation:UITableViewRowAnimationFade];
    [tableView endUpdates];
    [self moreStories];
} else { 
    NSLog(@"%@",[[stories objectAtIndex: storyIndex] objectForKey: @"link"]);
    webViewController *webController;
    webController = [[webViewController alloc] initWithURLPassed:[[stories objectAtIndex: storyIndex] objectForKey: @"link"]];
    [self.navigationController pushViewController:webController animated:YES];
    [webController release];
    webController =nil;
    self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStylePlain target:nil action:nil];
}
}

【问题讨论】:

  • 在后台线程中执行 moreStories。像 [self performSelectorInBackground:@selector(moreStories:) withObject:nil];然后,您需要在 moreStories 方法中创建一个新的 NSAutoReleasePool 并在方法结束时将其排空。

标签: ios objective-c iphone uitableview cocoa-touch


【解决方案1】:

[tableView dequeueReusableCellWithIdentifier:@"more"] 告诉表格视图给你一个不同的单元格,一个在重用队列中而不是正在显示的单元格中。此外,moreCell == nil 条件在没有可重用单元可用于出列时生成 全新 单元。此模式仅供表格视图数据源在生成用于显示的表格单元格时使用。

您需要使用[tableView cellForRowAtIndexPath:indexPath] 来获取实际选择的单元格。

UITableViewCell *moreCell = [tableView cellForRowAtIndexPath:indexPath];
moreCell.textLabel.text = @"Loading...";

编辑:根据您的更新,正如 aBitObvious 在 cmets 中所说,URL 加载请求阻止了 UI 更新。在更新 UI 时,请尝试启动一个新线程并在该线程中加载数据,以便您的 UI 可以不受干扰地更新。

【讨论】:

  • 好的。这就说得通了。现在我有了这个,但它仍然无法工作: UITableViewCell *moreCell = [tableView cellForRowAtIndexPath:indexPath]; moreCell.textLabel.text = @"加载中..."; [tableView deselectRowAtIndexPath:indexPath 动画:YES]; [自我更多故事];
  • 设置文本后尝试调用[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
  • @Josh:嗯,我现在很困惑,很抱歉。
  • 好的。是的,这是一个奇怪的问题。从我在网上阅读的所有内容来看,看起来我做的每一件事都是正确的,但它只是不起作用。感谢您的帮助。
  • @Josh,你应该用 moreStories 的描述来更新你的问题。除了按照 BoltClock 的建议使用 cellForRowAtIndexPath 之外,您还需要以不同的方式调用 moreStories 以避免它阻塞 ui(url 加载可能会这样做)。
【解决方案2】:

我继续做了一个非常简单的版本来说明你想要完成的事情。看看这是否有帮助。我做到这一点的方式是我继续并更改了 UITableView 的数据源。最终您可能会这样做以加载更多故事。要记住的关键是,如果您要更改数据源,则需要重新加载 tableView。

- (void)viewDidLoad {

  NSArray *array = [[NSArray alloc] initWithObjects:@"Story 1", @"Story 2", @"Story 3", @"Story 4", @"Story 5", @"More Stories", nil];
  self.stories = array;
  [array release];

  [super viewDidLoad];
}

//TableView 数据源方法

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section  
 {
   return [stories count];
 }

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

  static NSString *CellIdentifier = @"CellIdentifier";
  UITableViewCell *cell = [table dequeueReusableCellWithIdentifier:CellIdentifier]; 
  if (cell == nil) {
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier: CellIdentifier] autorelease];
  }

  cell.textLabel.text = [stories objectAtIndex:[indexPath row]];
  return cell;
 }

//TableView 委托方法

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

if ([indexPath row] == [stories count] - 1) {
    //Get more stories
    [table deselectRowAtIndexPath:indexPath animated:YES];

    NSArray *array = [[NSArray alloc] initWithObjects:@"Story 1*", @"Story 2*", @"Story 3*", @"Story 4*", @"Story 5*", @"Loading...", nil];
    self.stories = array;
    [array release];

    NSArray *arr = [[NSArray alloc] initWithObjects:indexPath,nil];

    [table beginUpdates];
    [table reloadRowsAtIndexPaths:arr withRowAnimation:UITableViewRowAnimationFade];
    [table endUpdates];
}
else {
    //Call your methods to load the stories.
}

【讨论】:

  • 好的。我在代码中添加了 beginUpdates、reloadRows 和 endUpdates 部分,现在单元格取消选择并将其文本更改为加载一瞬间,在新故事加载之后但在它们出现之前。即我点击该行,它变成蓝色,所有故事下载,该行取消选择,并将文本更改为“正在加载...”一瞬间,然后故事出现。在它永远不会将文本更改为“正在加载...”之前,因此代码似乎取得了一些进展。但我显然希望它在故事开始下载之前取消选择并将文本更改为“正在加载...”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-29
  • 1970-01-01
  • 2021-11-08
  • 2017-11-16
  • 2010-10-12
  • 2020-11-06
相关资源
最近更新 更多