12

Here is my source code

- (id)initWithCollectionView:(UICollectionView *)collectionView
{
self = [super init];

if (self)
{
    self.collectionView = collectionView;
    self.collectionView.dataSource = self;
    self.collectionView.delegate = self;
    [self.collectionView registerClass:[TWNTweetCell class] forCellWithReuseIdentifier:kCell];
    self.collectionViewLayout = self.collectionView.collectionViewLayout;



    self.tweetArray = @[];
    self.tweetTextArray = @[];

    self.twitter = [STTwitterAPI twitterAPIOSWithFirstAccount];
}

return self;
}

#pragma mark - CollectionView
#pragma mark DataSource

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

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

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
TWNTweetCell *cell = (TWNTweetCell *)[collectionView dequeueReusableCellWithReuseIdentifier:kCell forIndexPath:indexPath];

NSDictionary *status = [self.tweetArray objectAtIndex:indexPath.row];

NSString *text = [status valueForKey:@"text"];

cell.usernameLabel.text = screenName;
//    cell.createdAtLabel.text = dateString;

cell.autoresizingMask = UIViewAutoresizingFlexibleWidth;

UITextView *textView = [self.tweetTextArray objectAtIndex:indexPath.row];
[cell setTweet:text withTweetTextView:textView];

return cell;
}

All the methods don't get interupted at all by breakpoints. The tweets are getting loaded in the log so I know everything else is ok, its just not recognizing the collection view. And yes i've set the

Anyone have any idea whats going on?

Justin Cabral
  • 565
  • 1
  • 6
  • 20
  • 1
    Are you calling the correct init method? Have you a set a breakpoint there? By the way, your tweetArray seems to be empty as well. – Tim Oct 06 '13 at 22:00

7 Answers7

50

It is not your case, it might be helpful for others who will came here having problem with data source methods not being called. It could be assigning data source like:

collectionView.dataSource = MyDataSource()

which is wrong as dataSource is a weak reference so it needs to be stored by some strong reference to be alive after creating it. Added a private property in a ViewController to keep the strong reference, initialising and then assigning it fixes the issue.

Julian
  • 9,299
  • 5
  • 48
  • 65
  • Came here with this problem without seeing this answer -> after a lot of debugging I found out it had to do with a weak reference -> wanted to add an answer here -> found your answer . Thanks anyway! Your answer would have save me some time if I looked better! – Menno Jun 14 '18 at 16:22
  • Good catch. Thanks Julian – KSR May 06 '19 at 06:24
4

A few suggestions:

  • Do all your UICollectionView setup and configuration in viewDidLoad.
  • Ensure you calling the create init method from your other class
  • Your tweetArray is also empty, so if the number of items method is called, it will return nothing and the other methods will not be called
Tim
  • 8,932
  • 4
  • 43
  • 64
3

A couple things:

1) in (and only in) your "init" method, use the underlying instance variable for your @property. That is,

_collectionView = collectionView;
_collectionView.dataSource = self;
_collectionView.delegate = self;

This is called "direct access", and more information can be seen in this related question.

2) in your .h file, make certain to declare that your object conforms to the data source & delegate protocols. E.G.

@interface JustinViewController : UIViewController <UICollectionViewDelegate, UICollectionViewDataSource>
Community
  • 1
  • 1
Michael Dautermann
  • 88,797
  • 17
  • 166
  • 215
2

for swift do this , set a property

//MARK: props
let dataSource = MyDataSource()

and in

viewDidLoad(){
// your other code 
..
..
collectionView.dataSource = dataSource // it is a strong reference 
}

apart form these other general pitfall are

  • not returning the count or the data source
  • not populating the data source
1

Add the collectionView to a view hierarchy.

In the init method you set the property (self.collectionView) but you do not add the collectionView to a view hierarchy. So the collectionView won't call any dataSource or delegate method.

user3378170
  • 2,371
  • 22
  • 11
0

I created collection view in storyboard and linked datasource and delegate but they were not being called in Xcode 8.0 with Swift 3.0. Tried multiple things but the solution was to declare the delegate and datasource in class declaration line:

class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource { ... }

Previously when we linked delegate and datasource through storyboard it was not required, may be a bug :)

Ali Awais
  • 113
  • 1
  • 9
-1

Call [collectionView reloadData] at the end of your init method. The collection view needs to be told to populate itself. I assume UICollectionViewController does this internally, but you don't seem to be using UICollectionViewController (or at least not in the usual way).

Timothy Moose
  • 9,895
  • 3
  • 33
  • 44
  • 3
    This is incorrect, you do not need to call reloadData for an initial load. When setting the delegate and datasource, this is when the methods will be called. – Tim Oct 06 '13 at 21:57