iOS: переход Storyboard CollectionView не запускается

У меня есть контроллер UICollectionView, встроенный в контроллер навигации. В collectionView перечислены проекты, и предполагается, что каждая ячейка переходит на экран ProjectDetail.

Я просто не могу запустить переход. Если я просто нажму кнопку на панели навигации и подключу переход к деталям, это сработает. Но запуск из моей ячейки CollectionView не работает.

Вот как выглядит раскадровка: http://cl.ly/RfcM У меня есть переход от CollectionViewCell в ProjectDetailViewController

Вот соответствующий код внутри моего ProjectDetailViewController:

@interface ProjectCollectionViewController () {
    NSArray *feedPhotos;
    Projects *projects;
}

@end

@implementation ProjectCollectionViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.collectionView registerClass:[FeedViewCell class] forCellWithReuseIdentifier:@"cell"];
    [self loadData];

}

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"selected %d", indexPath.row);
    Project *project = [projects getProject:indexPath.row];
    NSLog(@"project = %@", project);
}

- (void)loadData {

    [self.projectLoader loadFeed:self.username
                       onSuccess:^(Projects *loadedProjects) {
                           NSLog(@"view did load on success :  projects %@", loadedProjects);
                           projects = loadedProjects;

                           [self.collectionView reloadData];
                       }
                       onFailure:^(NSError *error) {
                           [self handleConnectionError:error];
                       }];
}


- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
   return projects.count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *identifier = @"cell";
    FeedViewCell *cell = (FeedViewCell *) [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
    cell.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:1.0 alpha:1.0];
    UIImageView *cellImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    Project *project = [projects getProject:indexPath.row];
    NSString *imageUrl = [project coverPhotoUrl:200 forHeight:200];
    NSLog(@"imageurl =>%@", imageUrl);
    if (imageUrl) {
        [cellImageView setImageWithURL:[NSURL URLWithString:imageUrl]];
    }
    [cell addSubview:cellImageView];
    cell.imageView = cellImageView;
    return cell;
}

Я предполагаю, что проблема где-то в том, как я подключаю ячейки к CollectionView.

Любая помощь будет принята с благодарностью!


person phil swenson    schedule 28.09.2013    source источник


Ответы (4)


Вы не можете создавать переходы непосредственно из ячеек в раскадровке, потому что представление коллекции заполняется динамически через источник данных. Вы должны использовать collectionView:didSelectItemAtIndexPath: и выполните переход программно, используя performSegueWithIdentifier:sender:. Что-то вроде этого:

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    [self performSegueWithIdentifier:@"MySegueIdentifier" sender:self];
}

где MySegueIdentifier — идентификатор перехода, определенный в раскадровке.

person Pulkit Goyal    schedule 28.09.2013
comment
Так может кто-нибудь сказать мне, что изменилось? Потому что здесь appcoda.com/ios-collection-view-tutorial мы можем ясно видеть, что соединение установлено в Storyboard и оно работает. - person Pahnev; 28.11.2014
comment
Этот ответ устарел. Определенно, вы можете создавать переходы прямо в раскадровке. - person Wael Showair; 15.06.2016

TLDR: ДЛЯ РАССКАЗКИ не вызывайте registerClass:forCellWithReuseIdentifier:. Он переопределяет то, что раскадровка устанавливает для ячейки (включая то, как обрабатываются переходы): Как установить UILabel в UICollectionViewCell

Краткая настройка

  • Использовал раскадровку
  • Создал новый контроллер представления коллекции, используя шаблон Xcode, установив его как подкласс UICollectionViewController.
  • Первоначально использовал UICollectionViewCell по умолчанию, программно добавляя UILabel.

Сгенерированный код UICollectionViewController зарегистрировал ячейку в viewDidLoad:

[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier];

Первая проблема: событие prepareForSegue:sender: не срабатывало, что привело меня к этому ответу. Я реализовал событие UICollectionViewDelegate и collectionView:didSelectItemAtIndexPath:, а затем программно вызвал переход. Это исправило мою первую проблему.

Вторая проблема: я переключился на пользовательскую ячейку, содержащую один ярлык. После того, как все подключил, метка ячейки не отображалась. После некоторого копания я нашел решение, содержащееся в ссылке вверху моего ответа.

Третья проблема и решение: я удалил строку registerClass:forCellWithReuseIdentifier:. Когда я запускал свое приложение, метка отображалась правильно, но когда я нажимал на ячейку, оно дважды вызывало событие prepareForSegue:sender. Удалив строку registerClass:forCellWithReuseIdentifier, ячейка обрабатывала касания ячейки напрямую, без необходимости использования метода делегата. Вот как я ожидал, что раскадровка будет работать. Я удалил событие collectionView:didSelectItemAtIndexPath:, которое разрешило двойное срабатывание prepareForSegue:sender:. Если вы используете раскадровку, не регистрируйте класс ячейки. Он перезаписывает настройки раскадровки.

person Luke    schedule 15.01.2015
comment
@Claude Знаете ли вы, почему использование collectionView:didSelectItemAtIndePath: перезаписывает настройки раскадровки? - person preynolds; 22.08.2015

Вы установили соединение с ячейкой CollectionView в Triggered Segues selection?

Вы также можете запустить переход программно, используя [self performSegueWithIdentifier:@"segueIdentifier" sender:nil]

in

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath

person mmackh    schedule 28.09.2013

Эквивалентный код Swift для аналогичного вопроса.

override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
    self.performSegueWithIdentifier(@"TargetSegway", sender: self)
} 

Убедитесь, что в случае, если в вашей ячейке есть другие перекрывающиеся представления, "Взаимодействие пользователя включено" не отмечено (вы можете найти этот параметр в инспекторе атрибутов "Вид/Взаимодействие"). В противном случае ваш жест касания используется перекрывающимся представлением, и didSelectItemAtIndexPath может не вызываться.

person brbabu    schedule 18.08.2015