5

since I couldn't use any framework to create an photo album, I'm trying to create my own using Collection View, but I got stuck right at the beginning.

My goal is to display all images from my web service into my collection view, since all displayed, the next step is when someone taps on any cell, I can open it in a new view and also navigate between all.

here is the basic code that I created:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [collectionController reloadData];
    tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:nil action:@selector(touched)];

    tapGesture.numberOfTapsRequired = 1;


}

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

-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{

    return 1;

}

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{

    return 6;
}

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{

    static NSString *cellIdentifier = @"Cell";

    CollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
    [cell.imgCollection setImageWithURL:[NSURL URLWithString:@"http://sallescds.com.br/wp-content/uploads/2012/12/xepop-300x300.jpg"] placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

    [cell.imgCollection addGestureRecognizer:tapGesture];

    return cell;
}

-(void)touched:(UIGestureRecognizer *)tap{

    NSLog(@"the touch happened");
}

thanks guys.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
César Martins
  • 95
  • 1
  • 1
  • 6

1 Answers1

14

A couple of things are not right in your code:

First, initWithTarget:action: should not be passed a nil value for target. From the docs :

target

An object that is the recipient of action messages sent by the receiver when it recognizes a gesture. nil is not a valid value.

In your case you should pass self as a target because you want to sent the message touched: to the current instance of your class.

Second, the selector you passed to initWithTarget:action: is wrong. You used @selector(touched) but your method implementation is - (void)touched:(UIGestureRecognizer *)tap;, which selector is @selector(touched:) (mind the :).

I'd recommend reading this question on selectors if your are confused.

Third, you cannot attach a single UIGestureRecognizer to multiple view (see this SO question).

So to make it work, you could create one UITapGestureRecognizer per collection cell (maybe in a subclass). Or better yet, implement your UICollectionViewDelegate method collectionView:didSelectItemAtIndexPath:.

EDIT - How to implement collectionView:didSelectItemAtIndexPath::

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    // Bind the collectionView's delegate to your view controller
    // This could also be set without code, in your storyboard
    self.collectionView.delegate = self;
}

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

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return 6;
}

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{

    static NSString *cellIdentifier = @"Cell";

    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
    [cell.imgCollection setImageWithURL:[NSURL URLWithString:@"http://sallescds.com.br/wp-content/uploads/2012/12/xepop-300x300.jpg"] placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

    return cell;
}

// I implemented didSelectItemAtIndexPath:, but you could use willSelectItemAtIndexPath: depending on what you intend to do. See the docs of these two methods for the differences.
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    // If you need to use the touched cell, you can retrieve it like so
    UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];

    NSLog(@"touched cell %@ at indexPath %@", cell, indexPath);
}
Community
  • 1
  • 1
Guillaume Algis
  • 10,705
  • 6
  • 44
  • 72
  • Got it, I already fixed these problems, my mistake when I was translating my methods names to english. Thanks for the help, now I have to figure it out, how to do this in the UICollectionViewDelegate, because I have no idea. Could you give me an example or something like that ? – César Martins Jun 05 '13 at 09:10
  • Ok, so I must call this method - (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath; and create the gesture inside it ? – César Martins Jun 05 '13 at 09:15
  • 2
    That is actually much more simple. If you implement the delegates methods, you don't need gesture recognizers. The delegate will call your implementation of its methods when a touch is detected. Note that you shouldn't need to call `shouldSelect..` or `didSelect..` explicitly, the delegate does this for you. – Guillaume Algis Jun 05 '13 at 09:27
  • 1
    I'd recommend searching for a good tutorial on how delegates works on the web, because they are a core part of any iOS app. – Guillaume Algis Jun 05 '13 at 09:28
  • I changed UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath]; to CollectionCell *cell = [collectionView cellForItemAtIndexPath:indexPath]; now I can use cell.imgCollection. Is that how I get the url ? – César Martins Jun 05 '13 at 09:36