iOS: Storyboard CollectionView segue not being triggered

◇◆丶佛笑我妖孽 提交于 2019-12-21 09:24:46

问题


I have a UICollectionView controller embedded inside a navigation controller. The collectionView lists projects and each cell is supposed to segue to a ProjectDetail screen.

I simply cannot get the segue to trigger. If I simply drop a button on the nav bar and hook up a segue to the detail, it works. But triggering from my CollectionView cell doesn't.

Here is what the storyboard looks like: http://cl.ly/RfcM I do have a segue hooked up from the CollectionViewCell to the ProjectDetailViewController

Here's the relevant code inside my 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;
}

I'm guessing the problem is somewhere in how I'm hooking up the Cells to the CollectionView.

Any help would be greatly appreciated!


回答1:


You cannot create segues directly from cells in a storyboard because the collectionview is populated dynamically through the data source. You should use the collectionView:didSelectItemAtIndexPath: and perform the segue programatically using performSegueWithIdentifier:sender:. Something like this:

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

where MySegueIdentifier is the identifier of the segue defined in storyboard.




回答2:


TLDR: FOR A STORYBOARD, do not call registerClass:forCellWithReuseIdentifier:. It overrides what the storyboard sets up for the cell (including how segues are handled): How to set a UILabel in UICollectionViewCell

Brief setup

  • Used a storyboard
  • Created a new collection view controller using the Xcode template, setting it as a subclass of UICollectionViewController.
  • Initially used the default UICollectionViewCell, adding a UILabel programmatically.

The generated UICollectionViewController code registered the cell in viewDidLoad:

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

First Issue: The prepareForSegue:sender: event was not firing, which brought me to this answer . I implemented the UICollectionViewDelegate and collectionView:didSelectItemAtIndexPath: event, then called the segue programmatically. This fixed my first issue.

Second Issue: I switched to a custom cell containing one label. After hooking everything up, the cell label was not displaying. After some digging, I found a solution contained in the link at the top of my answer.

Third Issue and Solution: I removed the registerClass:forCellWithReuseIdentifier: line. When I ran my app, the label appeared correctly, but when I tapped a cell, it called the prepareForSegue:sender event twice. By removing the registerClass:forCellWithReuseIdentifier line, the cell was processing cell touches directly, without the need of the delegate method. This is how I expected the storyboard to work. I deleted the collectionView:didSelectItemAtIndexPath: event, which resolved the double-firing of prepareForSegue:sender:. If you are using a storyboard, do not register the cell class. It overwrites what storyboard sets up.




回答3:


Have you made your CollectionView Cell's connection in Triggered Segues on selection?

You can also trigger a segue programatically using [self performSegueWithIdentifier:@"segueIdentifier" sender:nil]

in

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




回答4:


Equivalent Swift code for similar question.

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

Make sure, in case if your cell has other overlapping views, "User Interaction Enabled" is unchecked (you can find this option, under attribute inspector View/Interaction). Otherwise, your Tap Gesture is consumed by the overlapping view, didSelectItemAtIndexPath may not be called.



来源:https://stackoverflow.com/questions/19070791/ios-storyboard-collectionview-segue-not-being-triggered

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!