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.
Любая помощь будет принята с благодарностью!
4 ответа
Вы не можете создавать сегменты непосредственно из ячеек в раскадровке, потому что представление коллекции динамически заполняется источником данных. Вы должны использовать collectionView:didSelectItemAtIndexPath:
и выполнить передачу программно с помощью performSegueWithIdentifier:sender:
, Что-то вроде этого:
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
[self performSegueWithIdentifier:@"MySegueIdentifier" sender:self];
}
где MySegueIdentifier
идентификатор сегмента, определенный в раскадровке.
TLDR: для STORYBOARD, не вызывайте registerClass:forCellWithReuseIdentifier:. Он переопределяет то, что раскадровка настраивает для ячейки (включая то, как обрабатываются сегменты): как установить UILabel в UICollectionViewCell
Краткая настройка
- Использовал раскадровку
- Создан новый контроллер представления коллекции с использованием шаблона XCode, установив его в качестве подкласса UICollectionViewController.
- Изначально использовался UICollectionViewCell по умолчанию, программно добавляя UILabel.
Сгенерированный код UICollectionViewController зарегистрировал ячейку в viewDidLoad:
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier];
Первый выпуск: событие prepareForSegue: sender: событие не было запущено, что привело меня к этому ответу. Я реализовал UICollectionViewDelegate и collectionView:didSelectItemAtIndexPath: событие, а затем вызвал segue программно. Это исправило мою первую проблему.
Вторая проблема: я переключился на пользовательскую ячейку, содержащую одну метку. После подключения все, метка ячейки не отображалась. После некоторых поисков я нашел решение, содержащееся в ссылке в верхней части моего ответа.
Третий вопрос и решение: я удалил строку registerClass:forCellWithReuseIdentifier:. Когда я запустил свое приложение, ярлык появился правильно, но когда я коснулся ячейки, он дважды вызвал событие prepareForSegue: sender. Удалив строку registerClass: forCellWithReuseIdentifier, ячейка обрабатывала касания ячейки напрямую, без необходимости использования метода делегата. Вот как я ожидал, что раскадровка сработает. Я удалил collectionView:didSelectItemAtIndexPath: событие, которое разрешило двойное срабатывание prepareForSegue:sender:. Если вы используете раскадровку, не регистрируйте класс ячейки. Это переписывает то, что настраивает раскадровка.
Вы установили соединение с вашей CollectionView Cell в Triggered Segues
на selection
?
Вы также можете запустить передачу программно, используя [self performSegueWithIdentifier:@"segueIdentifier" sender:nil]
в
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
Эквивалентный код Swift для аналогичного вопроса.
override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier(@"TargetSegway", sender: self)
}
Убедитесь, что в том случае, если в вашей ячейке есть другие перекрывающиеся виды, флажок " Взаимодействие с пользователем включен " не установлен (вы можете найти эту опцию в Инспекторе атрибутов "Просмотр / взаимодействие"). В противном случае ваш Жест касания используется перекрывающимся видом, didSelectItemAtIndexPath может не вызываться.