Методы источника данных UICollectionView не вызывают, но устанавливаются в init

Вот мой исходный код

- (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;
}

Все методы вообще не прерываются точками останова. Твиты загружаются в журнал, поэтому я знаю, что все в порядке, просто не распознается представление коллекции. И да, я установил

У кого-нибудь есть идеи, что происходит?

7 ответов

Это не ваш случай, это может быть полезно для тех, кто приедет сюда, имеющих проблемы с не вызываемыми методами источника данных. Это может быть назначение источника данных, как:

collectionView.dataSource = MyDataSource()

что неверно, так как dataSource является слабой ссылкой, поэтому он должен быть сохранен какой-либо сильной ссылкой, чтобы быть живым после его создания. Добавил частное свойство в ViewController для сохранения строгой ссылки, инициализация и последующее назначение которого решают проблему.

Несколько предложений:

  • Сделай все свои UICollectionView настройка и настройка в viewDidLoad,
  • Убедитесь, что вы звоните создать init метод из вашего другого класса
  • Ваш tweetArray также пусто, поэтому, если вызывается метод number of items, он ничего не возвратит и другие методы не будут вызваны

Пара вещей:

1) в (и только в) твое "init"метод, используйте базовую переменную экземпляра для вашего @property.

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

Это называется "прямой доступ", и в этом связанном вопросе можно увидеть больше информации.

2) в своем файле.h обязательно укажите, что ваш объект соответствует протоколам источника данных и делегатов. НАПРИМЕР

@interface JustinViewController : UIViewController <UICollectionViewDelegate, UICollectionViewDataSource>

Для быстрого сделайте это, установите свойство

//MARK: props
let dataSource = MyDataSource()

И в

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

кроме формы эти другие общие ловушки

  • не возвращает счет или источник данных
  • не заполняет источник данных

Добавьте collectionView в иерархию представлений.

В методе init вы устанавливаете свойство (self.collectionView), но не добавляете collectionView в иерархию представления. Таким образом, collectionView не будет вызывать какой-либо источник данных или метод делегата.

Я создал представление коллекции в раскадровке и связанном источнике данных и делегате, но они не вызывались в Xcode 8.0 с Swift 3.0. Пробовал несколько вещей, но решением было объявить делегат и источник данных в строке объявления класса:

Класс ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource { ... }

Ранее, когда мы связывали делегат и источник данных через раскадровку, это не требовалось, это может быть ошибкой:)

Вызов [collectionView reloadData] в конце вашего init метод. Представление коллекции нужно сказать, чтобы заполнить себя. Я предполагаю UICollectionViewController делает это внутренне, но вы, кажется, не используете UICollectionViewController (или, по крайней мере, не обычным способом).

Другие вопросы по тегам