3

首先,我想说我只是提出这个问题,因为我想了解正在发生的事情。

我在 Xcode5 的全新安装中打开了一个旧的 Xcode 项目(一个非常简单的项目)。当我意识到它在 iOS 7 上不起作用时。为什么?不知道。。

看到了一些其他的问题,没有得到任何有用的答案,所以我做了一个简单的测试。在UITableViewController所有工作正常,除了didSelectRowAtIndexPath

看看这个

RootViewController.h:

@interface RootViewController : UITableViewController

@property (strong, nonatomic) NSMutableArray *items;
@end

RootViewController.m 在 vi​​ewDidLoad 中我初始化了数组(带有一些字符串)。

实现dataSource和delegate方法(是的,我将delegate和dataSource设置为tableView)

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

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    // Configure the cell...
    cell.textLabel.text = [_items objectAtIndex:indexPath.row];

    return cell;
}

问题在这里:

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Navigation logic may go here, for example:
    // Create the next view controller.
    DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];

    // Push the view controller.
    [self.navigationController pushViewController:detailViewController animated:NO];

    detailViewController.detailLabel.text = [_items objectAtIndex:indexPath.row];
}

DetailViewController是一个简单的 UIViewController:

(是的,我在 nib 文件上设置了 IBOutlet)

@interface DetailViewController : UIViewController
@property (weak, nonatomic) IBOutlet UILabel *detailLabel;

@end

问题是这在 iOS7 上不起作用,标签DetailViewController没有更新。我尝试在pushViewController.

这适用于所有早期版本的 iOS。

为什么不能在 iOS 7 上运行?

我得到这个工作的唯一方法是,就像我在另一个问题上看到的那样:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Navigation logic may go here, for example:
    // Create the next view controller.
    DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];

    // Push the view controller.
    [self.navigationController pushViewController:detailViewController animated:YES];

    dispatch_async(dispatch_get_main_queue(), ^{
        detailViewController.detailLabel.text = [_items objectAtIndex:indexPath.row];
    });
}

有人可以帮我了解这里发生了什么吗?

谢谢!

_

编辑

它也可以这样工作:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Navigation logic may go here, for example:
    // Create the next view controller.
    DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];

    // Push the view controller.
    [self.navigationController pushViewController:detailViewController animated:YES];

    if (detailViewController.view) {
        // do notihing
    }
    detailViewController.detailLabel.text = [_items objectAtIndex:indexPath.row];
}
4

2 回答 2

8

在你设置UILabel的值的时候,视图还没有加载,所以如果你在debug中签入,你可能会发现detailLabel是nil。

为什么不在自定义 init 方法中传递值?例如

- (id)initWithDetails:(NSString *)detailsText;

那么在viewDidLoad中,赋值呢?

根据您的编辑,回答您关于它为何起作用的问题:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    TestViewController *test = [[testViewController alloc] init];

    NSLog(@"Before: %@", test.label);

    if(test.view){}

    NSLog(@"After: %@", test.label);

    [[test label] setText:@"My Test"];

    [self.navigationController pushViewController:test animated:YES];
}

我已经模拟了您的场景,如果您在 ViewController 上访问“视图”,如果视图不存在,它将调用 viewDidLoad。因此,您的 UILabel 现在已设置。这是控制台的输出。

2013-10-11 16:21:04.555 test[87625:11303] Before: (null)
2013-10-11 16:21:04.559 test[87625:11303] After: <UILabel: 0x75736b0; frame = (148 157; 42 21); text = 'Label'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x7573740>>

我建议使用自定义的 init 方法,而不是这种方法——上面的例子是一个 hack。使用类似这样的东西

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    testViewController *test = [[testViewController alloc] initWithText:@"My Test"];

    [self.navigationController pushViewController:test animated:YES];
}

如果您不想使用自定义初始化程序,我建议您在 DetailViewController 上使用 NSString 类型的公共属性。在调用 init 后使用您的方法分配它。然后在 DetailViewController 中,在 viewDidLoad 或出现时,将 IBOutlet 设置为包含 NSString 的属性的值。

于 2013-10-11T15:08:03.893 回答
0

它没有更新,因为您正在编写 @property (weak, nonatomic) IBOutlet UILabel *detailLabel; 您正在使 UILabel 成为弱属性。你必须使它成为强大的属性。@property(强,非原子)IBOutlet UILabel *detailLabel; 当你让你的财产变得脆弱时,它就会被摧毁。

要了解有关弱属性和强属性的更多信息,您可以参考 Objective-C 中强与弱之间的差异

于 2015-09-21T11:03:13.857 回答