tableView didSelectRowAtIndexPath在iOS 7上无法正常工作。为什么? [英] tableView didSelectRowAtIndexPath doesn't work properly on iOS 7. Why?

查看:116
本文介绍了tableView didSelectRowAtIndexPath在iOS 7上无法正常工作。为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我想说我只是提出这个问题,因为我想了解发生了什么。

In first place I would like to say that I'm only making this question, because I would like to understand what is happening.

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

I opened an old Xcode project (a very simple one) in a fresh installation on Xcode5. When I realize that it doesn't work on iOS 7. Why? Don't know..

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

I saw some other questions, didn't get any useful answer, so I made a simple test. In the UITableViewController all works fine except on didSelectRowAtIndexPath

检查出来

RootViewController.h:

RootViewController.h:

@interface RootViewController : UITableViewController

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

RootViewController.m
在viewDidLoad中我初始化数组(带一些字符串)。

RootViewController.m In viewDidLoad I init the array (with some strings).

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

Implement the dataSource and delegate methods (and yes I set the delegate and dataSource to the 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:

DetailViewController is a simple UIViewController:

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

(yes, I set the IBOutlet on nib file)

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

@end

问题是这在iOS7上不起作用, DetailViewController 中的标签未更新。我尝试在 pushViewController 之前和之后设置标签文本。

The problem is that this doesn't work on iOS7, the label in DetailViewController doesn't get updated. I try to set the label text before and after of pushViewController.

这适用于以前的所有版本iOS版。

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

我实现这一目标的唯一方法就像我在其他问题上看到的那样:

The only way I get this working is, like I saw on this other question:

- (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];
}


推荐答案

当你设定的时候UILabel的值,视图尚未加载,所以如果你检查调试,你可能会发现detailLabel是nil。

At the time when you set the value of the UILabel, the view has not yet been loaded, so if you check in debug, you'll probably find detailLabel is nil.

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

Why not pass the value in a custom init method? e.g.

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

然后在viewDidLoad中,分配值?

Then in viewDidLoad, assign the value?

根据你的编辑,回答你的问题,为什么它工作:

According to your edit, in answer to your question as to why it is working:

- (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上访问'view',我已经模拟了你的场景,如果视图不存在,它将调用viewDidLoad。所以你的UILabel现在已经定了。这是控制台的输出。

I have mocked up your scenario, if you access 'view' on a ViewController, it will call viewDidLoad if the view does not exist. So your UILabel now becomes set. Here is the output from the console.

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。使用类似的东西例如

I recommend using a custom init method, rather than this approach - this above example is a hack. Use something like this E.g.

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

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

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

If you do not wish to use a custom initialiser, I suggest a public property on your DetailViewController of type NSString. Assign that using your approach after init is called. Then within DetailViewController, in viewDidLoad, or appear, set the IBOutlet to the value of the property containing the NSString.

这篇关于tableView didSelectRowAtIndexPath在iOS 7上无法正常工作。为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆