【问题标题】:Screen doesn't update when I change a UILabel's text当我更改 UILabel 的文本时屏幕不更新
【发布时间】:2015-06-20 09:53:59
【问题描述】:

我的环境是 Xcode 6.3,目标是 iOS8.3 for iPad。 我正在使用 Xcode 的模板学习 Master-Detail 视图。当我尝试在详细视图中设置标签的文本时出现一些奇怪的问题:
如果我将更改标签文本的语句放在 P1 位置,它会起作用。
但是如果我把语句放在 P2 位置,它就不起作用了。

在这两种情况下,detailDescriptionLabel.text 都发生了变化,但实际上只有 P1 语句更新了屏幕。(我检查过函数 configureView() 被调用了两次)

有人可以帮助我吗?非常感谢。

下面是我的代码sn-ps:

MasterController.m:

#import "MasterViewController.h"
#import "DetailViewController.h"

@interface MasterViewController ()

@property (copy, nonatomic) NSMutableArray *objects;

@end

@implementation MasterViewController

- (void)awakeFromNib {
    [super awakeFromNib];
    self.clearsSelectionOnViewWillAppear = NO;
    self.preferredContentSize = CGSizeMake(320.0, 600.0);
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    NSString *path = [[NSBundle mainBundle] pathForResource:@"PresidentList" ofType:@"plist"];
    NSDictionary *presidentInfo = [NSDictionary dictionaryWithContentsOfFile:path];
    self.objects = [NSMutableArray arrayWithArray:[presidentInfo objectForKey:@"presidents"]];

    self.detailViewController = (DetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Segues

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([[segue identifier] isEqualToString:@"showDetail"]) {
        DetailViewController *controller = (DetailViewController *)[[segue destinationViewController] topViewController];
        controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem;
        controller.navigationItem.leftItemsSupplementBackButton = YES;

        //P1
        //controller.detailItem = (self.objects[indexPath.row])[@"url"];
    }
}



#pragma mark - Table View

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.objects.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

    cell.textLabel.text = (self.objects[indexPath.row])[@"name"];
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    //P2
    //self.detailViewController.detailItem = (self.objects[indexPath.row])[@"url"];
}
@end

DetailController.m:

#import "DetailViewController.h"

@interface DetailViewController ()
@property (strong, nonatomic) UIPopoverController *masterPopoverController;
@end

@implementation DetailViewController

#pragma mark - Managing the detail item

- (void)setDetailItem:(id)newDetailItem {
    if (_detailItem != newDetailItem) {
        _detailItem = newDetailItem;
        // Update the view.
        [self configureView];
    }
    if (self.masterPopoverController != nil) {
        [self.masterPopoverController dismissPopoverAnimated:YES];
    }
}

- (void)configureView {
    // Update the user interface for the detail item.
    if (self.detailItem) {
        self.detailDescriptionLabel.text = self.detailItem;
    }
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self configureView];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Split view

- (void)splitViewController:(UISplitViewController *)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)pc {
    barButtonItem.title = NSLocalizedString(@"Master", @"Master");
    [self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES];
    self.masterPopoverController = pc;
}

- (void)splitViewController:(UISplitViewController *)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem {
    [self.navigationItem setLeftBarButtonItem:nil animated:YES];
    self.masterPopoverController = nil;
}
@end

【问题讨论】:

  • 不确定问题是什么。您非常正确地证明了位置 P1 是正确的,而位置 P2 是错误的。 - 您可以尝试在 P2 位置记录self.detailViewController,以了解更多信息...
  • 其实detailViewController很简单,我把整个文件放在这里了。我就是找不到什么特别的东西。

标签: ios objective-c xcode uilabel master-detail


【解决方案1】:

我猜 self.detailViewController 是 nil。因此 P2 将无法工作。

如果没有看到所有代码很难说,但在 prepareForSegue 中,您可能希望将其分配在那里。

【讨论】:

  • 我检查过它不是零。也许将初始化代码放在 prepareForSegue() 中是个好主意,我只是好奇 P1 和 P2 有什么区别:)
【解决方案2】:

我猜你正在使用 segues,这就是使用专门指定的专用函数 (prepareForSegue) 来在创建视图目标视图之后初始化值的重点。

除非您在didSelectRowAtIndexPath 中自己实例化并显示视图,否则为这样的视图控制器设置一些东西是没有意义的。

【讨论】:

  • 是的,你是对的。我只是想知道如果 UILabel 的文本发生了变化,视图不应该也更新吗?
  • @ZhuShengqi 仅当视图,uilabel 到主事件循环层次结构。这里的问题是你已经有一个由 segue 自动生成的视图控制器,但是在 P2 位置你正在创建第二个视图控制器,它永远不会显示,并且你正在修改它而不是显示的那个。
  • 我明白你的意思,非常感谢。我应该多研究苹果提供的机制:)
猜你喜欢
  • 2017-09-24
  • 2022-12-15
  • 1970-01-01
  • 2016-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-29
  • 1970-01-01
相关资源
最近更新 更多