更改 UITableViewCell 附件后 UITableViewCellAccessoryDe​​tailDisclosureButton 消失

Posted

技术标签:

【中文标题】更改 UITableViewCell 附件后 UITableViewCellAccessoryDe​​tailDisclosureButton 消失【英文标题】:UITableViewCellAccessoryDetailDisclosureButton disappearing after changing UITableViewCell accessory 【发布时间】:2013-04-02 00:38:03 【问题描述】:

我有一个UITableView,其中包含带有图像、文本和披露按钮的单元格。我正在像这样加载单元格:

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

    static NSString *cellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if(!cell) 
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
    

    if ([indexPath row] == [[self multas] count]) 
        [[cell textLabel] setText:@"Carregar mais..."];
     
    else 
    
        Multa *multa = [self.multas objectAtIndex:indexPath.row];

        NSString *dataIsolada = [[NSString stringWithFormat:[multa dataOcorrencia]] substringWithRange:NSMakeRange(0, 10)];

        [[cell textLabel] setText:[NSString stringWithFormat:dataIsolada]];
        [[cell detailTextLabel] setText:[multa descricao]];
        [cell.imageView setImageWithURL:[NSURL URLWithString:[multa fotoURL]]
                       placeholderImage:[UIImage imageNamed:@"carregando.jpeg"]];
        [cell.imageView setContentMode: UIViewContentModeScaleAspectFit];
        [cell setAccessoryType:UITableViewCellAccessoryDetailDisclosureButton];
    

    return cell;

当用户点击显示按钮时,我将显示按钮切换为活动指示器,然后使用导航控制器将另一个视图推送到屏幕:

- (void)carregarDetalhesMulta:(UITableView *)tableView comMulta:(Multa *)multa 

    DetalheMultaViewController *form = [[DetalheMultaViewController alloc] initWithMulta:multa];
    form.delegate = self;

    UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:form];

    [self presentModalViewController:navigation animated:YES];


- (void) tableView: (UITableView *) tableView accessoryButtonTappedForRowWithIndexPath: (NSIndexPath *) indexPath

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleGray];
    spinner.frame = CGRectMake(0, 0, 24, 24);
    cell.accessoryView = spinner;
    [spinner startAnimating];

    Multa *multa = [self.multas objectAtIndex:indexPath.row];

    double delayInSeconds = 0.1;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);

    dispatch_after(popTime, dispatch_get_main_queue(), ^(void)

       [spinner stopAnimating];
       [self carregarDetalhesMulta:tableView comMulta:multa];
       [cell setAccessoryType:UITableViewCellAccessoryDetailDisclosureButton];
    );


请注意,我最后将附件改回了一个披露按钮。问题是:当我返回(通过点击返回按钮)到包含UITableView 的视图时,我点击的行没有显示任何披露按钮或活动指示器。我做错了什么?在无需重新加载表格视图的情况下切换这些控件的更好方法是什么?

【问题讨论】:

使 cell.accessoryView = NULL;然后使用你的代码 【参考方案1】:

accessoryView 属性优先于accessoryType 属性。如果您将accessoryView 设置为nil,您将再次看到附件按钮。

【讨论】:

【参考方案2】:

这是我从问题中了解到的:您希望附件视图成为一个披露按钮,当点击该按钮时,它会成为一个活动指示器。短暂延迟后,您想推送到新的视图控制器。

我会这样做:

    将情节提要中的原型单元设置为 Accessory:none。 从你的视图控制器中添加一个 push segue 到你想要的目标 vc,给它一个标识符,比如 @"MyPushSegue"

将附件视图添加到 cellForRowAtIndexPath 中的单元格(如果没有的话):

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
    // the rest of your cellForRowAtIndexPath

     if (!cell.accessoryView)
        cell.accessoryView = [self createAccessoryView];

    return cell;

以这种方式创建附件视图(假设为 ARC):

- (UIView *)createAccessoryView 

    UIView *accessoryView = [[UIView alloc] initWithFrame:CGRectZero];
    UIButton *disclosureButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];

    disclosureButton.tag = 100;
    [disclosureButton addTarget:self action:@selector(pressedAccessory:) forControlEvents:UIControlEventTouchUpInside];

    UIActivityIndicatorView *aiv = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    aiv.tag = 101;
    aiv.alpha = 0.0;
    aiv.center = disclosureButton.center;

    accessoryView.bounds = disclosureButton.bounds;
    [accessoryView addSubview:aiv];
    [accessoryView addSubview:disclosureButton];
    return accessoryView;

上面的公开按钮在按下按钮时触发一个方法。此方法应更改选择器视图的状态并触发您在情节提要中设置的 push segue:

- (void)pressedAccessory:(UIButton *)sender 

    UIView *accessoryView = sender.superview;
    [self setAccessoryView:accessoryView waiting:YES];

    // let the user see the spinner for 1 seconds
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC);
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void) 
        [self performSegueWithIdentifier:@"MyPushSegue" sender:self];
        [self setAccessoryView:accessoryView waiting:NO];
    );

最后,为了解决您遇到的问题,我们不会用微调器替换附件视图,而是通过隐藏/显示按钮和隐藏/显示微调器来改变它的外观,具体取决于我们想要的状态:

- (void)setAccessoryView:(UIView *)accessoryView waiting:(BOOL)waiting 

    UIButton *disclosureButton = (UIButton *)[accessoryView viewWithTag:100];
    UIActivityIndicatorView *aiv = (UIActivityIndicatorView *)[accessoryView viewWithTag:101];
    [UIView animateWithDuration:0.1 animations:^
        disclosureButton.alpha = (waiting)? 0.0 : 1.0;
        aiv.alpha = (waiting)? 1.0 : 0.0;
    ];

    if (waiting) [aiv startAnimating]; else [aiv stopAnimating];

【讨论】:

也许这样做我会达到我所需要的,但现在斯科特的回答解决了我的问题。稍后我不着急时会尝试这种方法。谢谢。

以上是关于更改 UITableViewCell 附件后 UITableViewCellAccessoryDe​​tailDisclosureButton 消失的主要内容,如果未能解决你的问题,请参考以下文章

更改 UITableViewCell 中的删除附件视图

在 UITableViewCell 的突出显示上更改附件视图

UITableViewCell 只在滚动后显示附件

在 iPad 上旋转 UITableView 后,UITableViewCell 附件未正确定位

iOS 15 - UITableViewCell 附件视图框架问题

添加附件时自定义 UITableViewCell 大小不正确