【问题标题】:UITableViewCell detailTextLabel does not update its text when new value is assigned to itUITableViewCell detailTextLabel 在分配新值时不会更新其文本
【发布时间】:2026-01-05 15:55:02
【问题描述】:

我一直在尝试使用静态表格视图作为我的应用程序中警报功能的设置/选项视图。我能够在各种 ViewController 和更新值之间来回传递和更新数据。

Ever MPMediaPickerController 会愉快地将数据传回,它甚至会在我保存值后使用正确的值更新委托,但在我保存警报对象之前它不会更新 detailTextLabel。我可以在我的日志中看到,当 ViewController 被解除时,对象甚至被保存为正确的值。唯一奇怪的是,有问题的 VC 是另一个 VC 的子 VC,但我认为这不是问题。

如果有帮助,所有 VC 也是 UINavigationController 的一部分,但 MediaPicker 除外。

我尝试重新加载数据,在主线程上执行更改,延迟主线程让所有更改执行,重新加载 mediaCell 所在位置的特定行,在单元格上调用 needsDisplay 和 needsLayout 和 layoutIfNeeded,什么都没有作品。任何建议都非常受欢迎,因为在过去的几天里我一直在反对这个并且感到沮丧。

#import "AddAlarmTableViewController.h"
#import "ToneTableViewController.h"

@interface AddAlarmTableViewController ()

@property (weak, nonatomic) IBOutlet UITableViewCell *mediaCell;

@end

@implementation AddAlarmTableViewController


@synthesize previousLabel, previousSoundAsset, previousRepeatArray,alarmDelegate,mediaCell;

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:NO];
    if(previousSoundAsset != nil) {
        mediaCell.detailTextLabel.text = previousSoundAsset;
    } else {
        mediaCell.detailTextLabel.text = @" ";
    }
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if([cell.reuseIdentifier isEqualToString:@"mediaCell"]) {
        UIAlertController *selectTypeAlertController = [UIAlertController alertControllerWithTitle:@"Select Media From" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
        //Creating actions
        UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil];
        UIAlertAction *selectFromMusicAction = [UIAlertAction actionWithTitle:@"Music" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
            [self launchMediaPickerController];
        }];
        UIAlertAction *selectFromToneAction = [UIAlertAction actionWithTitle:@"Tone" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
            [self launchTonePickerController];
        }];
        //adding them to uialertcontroller;
        [selectTypeAlertController addAction:cancelAction];
        [selectTypeAlertController addAction:selectFromMusicAction];
        [selectTypeAlertController addAction:selectFromToneAction];
        [self presentViewController:selectTypeAlertController animated:true completion:nil];

    }
}
- (void)launchTonePickerController {
    ToneTableViewController *toneVC = [[ToneTableViewController alloc] init];
    toneVC.alarmDelegate = alarmDelegate;
    [self.navigationController pushViewController:toneVC animated:true];

}
- (void)launchMediaPickerController {
    NSLog(@"Launching MPMediaPickerController");
    MPMediaPickerController *mediaPicker = [[MPMediaPickerController alloc] initWithMediaTypes:MPMediaTypeMusic];
    mediaPicker.delegate = self;
    mediaPicker.allowsPickingMultipleItems = NO;

    [self presentViewController:mediaPicker animated:true completion:nil];
}

//MPMediaPickerDelegate methods
- (void)mediaPickerDidCancel:(MPMediaPickerController *)mediaPicker {
    [self dismissViewControllerAnimated:true completion:^ {
        NSLog(@"MPMediaPickerController dismissed");
    }];
}
- (void)mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection {
    MPMediaItem *selectedTrack = [[mediaItemCollection items] objectAtIndex:0];
    alarmDelegate.soundAsset = selectedTrack.title;
    mediaCell.detailTextLabel.text = alarmDelegate.soundAsset;
    alarmDelegate.appTones = [[NSNumber alloc] initWithBool:NO];
    [self dismissViewControllerAnimated:true completion:^ {
        NSLog(@"MPMediaPickerController dismissed with %@", alarmDelegate.soundAsset);
        dispatch_async(dispatch_get_main_queue(), ^ {
            [self.tableView reloadData];
        });
    }];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if([segue.identifier isEqualToString:@"repeatSegue"]) {
        DayTableViewController *daysViewController = segue.destinationViewController;
        daysViewController.alarmDelegate = alarmDelegate;
        if(previousRepeatArray != nil) {
            daysViewController.previousSelection = previousRepeatArray;
        }
    }
    else if([segue.identifier isEqualToString:@"labelSegue"]) {
        LabelViewController *labelViewController = segue.destinationViewController;
        labelViewController.alarmDelegate = alarmDelegate;
        if(previousLabel != nil) {
            labelViewController.previousLabel = previousLabel;
        }
    }
}
@end

【问题讨论】:

  • 你确定outlet不是nil吗?
  • 是的,它不是零,我只是仔细检查了一遍。

标签: ios objective-c uitableview uiviewcontroller uikit


【解决方案1】:

请检查 previousSoundAsset 的值。它可能是空字符串(不是 nil)。

if(previousSoundAsset != nil || ![previousSoundAsset isEquals:@""]) {
    mediaCell.detailTextLabel.text = previousSoundAsset;
} else {
    mediaCell.detailTextLabel.text = @" ";
}

【讨论】:

  • 它不是,正如我上面所说,我可以清楚地看到价值正在被保存。当我保存它并返回编辑它时,它将显示更新的值。
  • 您可以在上述代码之前打印日志:NSLog(@"previousSoundAsset=%@", previousSoundAsset);
  • 我是说它不是 nil 或空的。
【解决方案2】:

好的,正如 Apple 文档所建议的那样,如果您正在使用情节提要和静态表格视图,建议您简单地将 IBOutlet 附加到相关项目并使用 IBOutlet 直接设置该项目的属性,在此案例,detailTextLabel。我仍然不明白为什么我不能通过在 didSelectRow UITableViewDelegate 中返回给我的单元格直接更改 detailTextLabel,但是你去。

我怀疑我之前没有尝试在主线程上的 GCD 块中执行此操作,所以也有。请注意,实际延迟的发生存在可察觉的延迟,因此也要注意这一点。

【讨论】:

    最近更新 更多