Неожиданное поведение при добавлении подпредставлений в UICollectionViewCell

В настоящее время я сталкиваюсь со странной проблемой с UICollectionViewCell при добавлении к нему подвидов, но только в определенных ситуациях.

Вот сценарий:

У меня есть представление «контейнера», которое соответствует очень специфическому протоколу (ADGControl) с вложенным представлением, обычно подклассом управления UIKit I.e MyCustomTextField: UITextField для пользовательских элементов управления.

Представление «контейнер» предоставляет свойство под названием «innerControlView», которое содержит сильную ссылку на настраиваемый элемент управления, который я пытаюсь добавить в качестве подпредставления к представлению содержимого ячейки.

Вот код:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
   FormControlCollectionViewCell *cell = [self.formCollectionView dequeueReusableCellWithReuseIdentifier:@"formControlCell" forIndexPath:indexPath];
   NSArray *sectionContents = [_controlList objectAtIndex:[indexPath section]];

   // This works
   //UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 315.0f, 30.0f)];
   //textField.borderStyle = UITextBorderStyleLine;
   //[cell.controlView addSubview:textField];

   // This doesn't (see the behaviour in video clip)
   id <ADGControl> control = [sectionContents objectAtIndex:[indexPath row]]; // The container view I'm referring to
   [cell.contentView addSubview:(UIView *)[control innerControlView]]; // [control innerControlView] is the typical UIKit control subclass for custom controls. In this example it will be a UITextField

   return cell;
}

Как вы можете видеть в комментариях к коду выше, всякий раз, когда я пытаюсь добавить только элемент управления UIKit (textField) напрямую, он работает просто отлично. Однако, как только я пытаюсь добавить свой пользовательский элемент управления ([control innerControlView], я получаю неожиданное поведение, как показано в видеоклипе здесь: http://media.shinywhitebox.com/ryno-burger/ios-simulator-ios-simulator-ipad-ios-a

Приведенная выше ссылка представляет собой всего лишь короткий 23-секундный видеоклип, чтобы лучше продемонстрировать «неожиданное поведение», которое я получаю.

Если кто-нибудь может указать, что я делаю неправильно, в чем может быть проблема, я буду благодарен.

Спасибо


person RynoB    schedule 09.10.2012    source источник
comment
Возможно, вы захотите переместить этот код (добавляя подпредставления) в подкласс. Потому что, если вы сделаете это таким образом, он будет добавлять его каждый раз, когда вызывается метод.   -  person Guido Hendriks    schedule 09.10.2012
comment
Хорошо, круто, но я не уверен, куда добавить его в моем подклассе UICollectionViewCell, так как я получаю экземпляр из dequeueReusableCellWithReuseIdentifier:. Я пробовал - (id)init, но он не вызывается. Мне трудно понять жизненный цикл UICollectionViewCell при использовании dequeueReusableCellWithReuseIdentifier, поэтому я не уверен, куда добавить свой код инициализации.   -  person RynoB    schedule 09.10.2012
comment
Извините, я хотел сказать - (id)initWithFrame. Однако он никогда не достигает моей точки останова в отладчике.   -  person RynoB    schedule 09.10.2012


Ответы (2)


Как вы можете прочитать в документации по UICollectionViewCells< /a>, вы не должны добавлять подвиды содержимого в саму ячейку, а в ее contentView.

И, как уже говорилось в моем комментарии, вы не должны добавлять подпредставления в источник данных, а в подкласс. Вы уже заметили, что initWithFrame: не вызывалось, вместо этого используйте initWithCoder::

-(id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        // Add your subviews here
        // self.contentView for content
        // self.backgroundView for the cell background
        // self.selectedBackgroundView for the selected cell background
    }
    return self;
}
person Guido Hendriks    schedule 11.10.2012
comment
Мне очень не нравится добавлять подвиды в саму ячейку, но что, если мой uiview заполняется источником данных? Я имею в виду, что я создаю несколько, используя информацию из источника данных. Я создал собственный класс ячеек и добавил представление в методе декодера. Я также заполняю свое представление в методе cellForIndexPath, но оно не отображается. Я получаю сбой в моем декодере, говоря, что мое представление равно нулю - person Ace Green; 28.06.2015

Представление может одновременно находиться только в одном суперпредставлении. Если это уже подвид вашего представления контейнера, вы не можете просто добавить его как подвид другого представления (вашей ячейки).

Не совсем понятно, почему вы используете представление как часть объекта модели, но вам придется либо изменить это, либо удалить внутреннее представление из его текущего суперпредставления, прежде чем добавлять его в ячейку.

person jrturton    schedule 09.10.2012
comment
Привет, я попытался добавить только представление контейнера, которое уже содержит представление внутреннего элемента управления, а не представление внутреннего элемента управления напрямую, но по-прежнему ведет себя так же, но немного отличается. Кажется, теперь все текстовые поля перезаписываются в одной ячейке. Оба представления имеют одинаковые рамки, имеет ли это значение? См. обновленный видеоклип: media.shinywhitebox. com/ryno-burger/ - person RynoB; 09.10.2012
comment
Думаю, GuidoH рассказал о вас в комментариях. Вы каждый раз добавляете одно и то же представление, даже для повторно используемых ячеек. - person jrturton; 09.10.2012