3

Во-первых, я хотел бы сказать, что я только задаю этот вопрос, потому что я хотел бы понять, что происходит.tableView didSelectRowAtIndexPath не работает должным образом на iOS 7. Почему?

Я открыл старый проект Xcode (очень простой) в новой установке на Xcode5. Когда я понимаю, что он не работает на iOS 7. Почему? Не знаю ..

Я видел несколько других вопросов, не получил никакого полезного ответа, поэтому я сделал простой тест. В UITableViewController все работает отлично, за исключением на didSelectRowAtIndexPath

Проверьте это

RootViewController.h:

@interface RootViewController : UITableViewController 

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

RootViewController.m В viewDidLoad я инициализировать массив (с некоторыми строками).

Реализовать DataSource и делегировать методы (да и я установить делегат и 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:

(да, я установил IBOutlet на файл nib)

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

@end 

Проблема в том, что это не работает на iOS7, метка в DetailViewController не обновляется. Я пытаюсь установить текст надписи до и после pushViewController.

Это работает со всеми предыдущими версиями iOS.

Почему не работает на iOS 7 ??

Единственный способ, которым я получить эту работу в том, что я видел на 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]; 
    }); 
} 

Может кто-нибудь помочь мне понять, что здесь происходит ??

Спасибо!

_

EDIT

также работает так:

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

вы пытаетесь поставить точку останова внутри этого метода увидеть, если это называется? –

+0

да, это называется. – Frade

+0

вы работаете на iPhone приложение? –

ответ

8

В то время, когда вы установите значение UILabel, вид еще не был загружен, так если вы проверите отладку, вы, вероятно, найдете detailLabel - это нуль.

Почему бы не передать значение в пользовательском методе инициализации? например

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

Then in 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>> 

Я рекомендую использовать собственный метод инициализации, а не этот подход - этот вышеприведенный пример является взломом. Используйте что-то вроде этого.

- (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.

+0

OP использует' initWithNibName: bundle: 'to создайте DetailViewController. Таким образом, когда это (первичное) представление будет доступно, иерархия представления будет загружена и настроена в соответствии с файлом nib. Это также должно вызывать 'viewDidLoad' для DetailViewController. Было бы целесообразно проверить, будет ли вызываться 'viewDidLoad'. И для тестирования для подтверждения вышеуказанного утверждения может быть вставлено заявление типа 'UIView * view = detailViewController.view;'. Кроме того, проверьте с помощью 'isViewLoaded'. – CouchDeveloper

+0

@CouchDeveloper Джефф прав. В исходном коде свойство метки имеет доступ задолго до того, как будет загружено представление контроллера представления. – rmaddy

+0

@maddy OK, будет 'detailViewController.view;' надлежащим обходным путем, чтобы заставить просмотр загружаться? Появляется хакерский. Есть ли лучшая идея? – CouchDeveloper

0

Не обновляется, потому что вы делаете запись @property (слабый, неатомный) IBOutlet UILabel * detailLabel; Вы создаете UILabel как слабое свойство. Вы должны сделать это сильным имуществом. @property (сильный, неатомный) IBOutlet UILabel * detailLabel; Как вы делаете вашу собственность слабой, так что ее уничтожение.

Чтобы узнать больше о слабых и сильных имущих вы можете обратиться Differences between strong and weak in Objective-C

Смежные вопросы