0

I have looked all over this website for 3 hours now and i cannot find out how to do this without referencing to manually connecting all of my 106 collection view cells with segues to another ViewController.

I would like to be able to click on my CustomCell (we will call it A) when i click on A i want to open a new viewController with the Page Title being A and the image i have set in the CustomCell to be the Page Logo within a UIImage on the view controller page.

I am aware this has to do with passing information between ViewControllers and i have no idea how to do this. Therefore i am very stuck.

I have only been using Xcode for a month now and i need it for my apprenticeship project so it would be very helpful if someone could help me.

My Current code is as follows, if someone is so kind enough to help please could you comment your code so that i get a further understanding as i don't just want to copy and paste the code and learn nothing from it.

Many thanks in advance.

ViewController.m

#import "GroupsViewController.h"
#import "GroupsHomeViewController.h"
#import "CustomCell.h"

@interface GroupsViewController ()
{
    NSArray *arrayOfImages;
    NSArray *arrayOfDescriptions;
}

@end

@implementation GroupsViewController
{
    NSString *reuseIdentifier;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[self GroupsCollectionView]setDataSource:self];
    [[self GroupsCollectionView]setDelegate:self];
    reuseIdentifier= @"SmallIcon";

    arrayOfImages = [[NSArray alloc]initWithObjects:@"A.png", nil];

    arrayOfDescriptions = [[NSArray alloc]initWithObjects:@"A",nil];
}

-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 1;
}

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return [arrayOfDescriptions count];
}


-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    CustomCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
    [[cell IconImage]setImage:[UIImage imageNamed:[arrayOfImages objectAtIndex:indexPath.item]]];
    [[cell IconLabel]setText:[arrayOfDescriptions objectAtIndex:indexPath.item]];

    return cell;
}

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

    [self performSegueWithIdentifier:@"customSegue" sender:indexPath];
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{

    NSIndexPath *indexPath = (NSIndexPath *)sender;
    UIImage *imageToShow = [UIImage imageNamed:[arrayOfImages objectAtIndex:indexPath.item]];
    NSString *titleToShow = [arrayOfDescriptions objectAtIndex:indexPath.item];
    GroupsHomeViewController * destination = (GroupsHomeViewController *)segue.destinationViewController;
    destination.groupLabel = *titleToShow; //assigning to UILabel form incompatible type NSString
    destination.logoImage = *imageToShow; // UIImageView from incompatible type UImage
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    //Dispose of any resources that can be recreated.
}

// Toggle View Button
- (IBAction)cellToggleAction:(id)sender {

    if([reuseIdentifier isEqualToString:@"SmallIcon"]){
        reuseIdentifier=@"ListView";
        [sender setImage:[UIImage imageNamed:@"LargeIcon"]];
    }
    else if
        ([reuseIdentifier isEqualToString:@"ListView"]){
        reuseIdentifier=@"LargeIcon";
        [sender setImage:[UIImage imageNamed:@"SmallIcon"]];
    }
    else if
        ([reuseIdentifier isEqualToString:@"LargeIcon"]){
        reuseIdentifier=@"SmallIcon";
        [sender setImage:[UIImage imageNamed:@"ListView"]];
    }

    [self.GroupsCollectionView reloadData];
}

//Toggled Cell Sizes
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {

    CGSize cellSize;

    if([reuseIdentifier isEqualToString:@"SmallIcon"])
        cellSize = CGSizeMake(100, 130);
    else if
        ([reuseIdentifier isEqualToString:@"ListView"])
        cellSize = CGSizeMake(320, 50);
    else if
        ([reuseIdentifier isEqualToString:@"LargeIcon"])
        cellSize = CGSizeMake(320, 350);

    return cellSize;
}

@end

GroupsHomeViewController.m where the groups view controller pay goes to.

#import "GroupsHomeViewController.h"

@interface GroupsHomeViewController ()

@end

@implementation GroupsHomeViewController

-(void)viewDidLoad{
    [super viewDidLoad];
    self.groupLabel.text = self.groupLabel; //incompatible pointertypes assigning to NSSstring
    self.logoImage.image = self.logoImage; //incompatible pointer types assigning to NSSstring

    // Do any additional setup after loading the view.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

CustomeCell.h

#import <UIKit/UIKit.h>

@interface CustomCell : UICollectionViewCell

@property (weak, nonatomic) IBOutlet UIImageView *IconImage;

@property (weak, nonatomic) IBOutlet UILabel *IconLabel;

@end
Lee Sugden
  • 63
  • 8
  • Also at current i have no connection between my GroupsViewController and my GroupsHomeViewController as i wanted to link these together via the collection view cells if that is possible? – Lee Sugden Feb 02 '16 at 20:59
  • 1
    Look up how to create a segue from your prototype cell to the new view controller. When the segue fires, you pass (title and image) details of the selected cell to the destination view controller (via `prepareForSegue`). –  Feb 02 '16 at 21:24

1 Answers1

0

Ok. This is a pretty big question. But first of all you would need to make a custom VC subclass for the target of the segue. You should definitely not have 106 different segues. Especially since it sounds like they will all be basically leading to the same place. A View controller that can show an image and a name. setup this new VC in your storyboard and make one segue from the viewController (not the cell) (Drag from the yellow circle ontop of the collection VC) to the new VC. and call it customSegue

SO setup a subclass something like:

    @interface SelectedInfoViewController : UIViewController
    @property (strong, nonatomic) NSString *selectedInfoName;
    @property (strong, nonatomic) UIImage *selectedInfoImage;
    @end

    @implementation SelectedViewController


-(void)viewDidLoad{
    [super viewDidLoad];
    self.labelForTitle.text = self.selecteInfoName;
    self.imageViewForImage.image = self.selecteInfoImage;
}

    @end

Then you would add to your collection view controller.

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

    [self performSegueWithIdentifier:@"customSegue" sender:indexPath];
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{

    NSIndexPath *indexPath = (NSIndexPath *)sender;
     UIImage *imageToShow = [UIImage imageNamed:[arrayOfImages objectAtIndex:indexPath.item]];
    NSString *titleToShow = [arrayOfDescriptions objectAtIndex:indexPath.item]];
    SelectedInfoViewController * destination = (SelectedInfoViewController *)segue.destinationViewController;
    destination.selectionInfoName = titleToShow;
    destination.selectionInfoImage = imageToShow;
}

Hope this makes some sense. Let me know if you need more help.

As per your errors:

destination.groupLabel = *titleToShow; //assigning to UILabel form incompatible type NSString
destination.logoImage = *imageToShow; // UIImageView from incompatible type UImage

self.groupLabel.text = self.groupLabel; //incompatible pointertypes assigning to NSSstring
self.logoImage.image = self.logoImage; //incompatible pointer types assigning to NSSstring

These are two separate things that you are assigning to each other. So as I highlighted you need to setup:

  @interface SelectedInfoViewController : UIViewController
        @property (strong, nonatomic) NSString *selectedInfoName;
        @property (strong, nonatomic) UIImage *selectedInfoImage;
but also we need:
        @property (strong, nonatomic) IBOutlet UILabel *infoLabel;
        @property (strong, nonatomic) IBOutlet UIImageView *infoImage;
        @end

Soooo. In the segue you should be setting the selectedInfoName, and selectedInfoImage. And then in the viewDidLoad you should be setting the infoLabel.text property to the passed selectedInfoName and the infoImage.image property to the passed selectedInfoImage.

Oh also as I had alluded before you need to link the infoLabel & infoImage to their respective counterparts in the storyboard.

Daniel Popov
  • 161
  • 5
  • yes you are correct into thinking that all of the segues are going to lead to the exact same page but will display slightly different content. So Ive controlled click between the two view controllers and created a segue but what type of segue does it need to be? just a show? or something different? and does the sub classed need to be a new file assigned to the segue? and do i need to add the remaining code into the view controller? Also thank you very much for your kind help. – Lee Sugden Feb 02 '16 at 21:56
  • "Show" is what you need. Yes the Create a new File -> Source -> Cocoa Touch Class. Subclass it to UIViewController name it what you want. Then back in Storyboard select the new VC and open up the identity inspector and set this new Class to it. – Daniel Popov Feb 02 '16 at 22:02
  • I just edited the part for the SelectedViewController to reflect how you should set this passed data in ViewDidLoad. In your storyboard I would setup a UILabel & UIImageView to show these items. Name them and add Outlets. Then set them as I showed. – Daniel Popov Feb 02 '16 at 22:07
  • Please can you check my updated code with comments? I'm not sure where about's i am going wrong many thanks – Lee Sugden Feb 02 '16 at 22:41
  • I have commented on the code where i am receiving errors... – Lee Sugden Feb 02 '16 at 22:46
  • I edited my response to highlight your errors. – Daniel Popov Feb 03 '16 at 02:30
  • If this response was helpful, please mark this answer as the accepted answer. – Daniel Popov Feb 03 '16 at 21:21