2013-11-20 2 views
5

Я пытаюсь анимировать между различными подклассами UICollectionViewFlowLayout. Каждый макет потока определяет другой размер элемента. В одной из них отображается сетка с тремя элементами, другая - сеткой с двумя элементами, а третья - только с одним элементом (выглядит как UITableView).Анимация Изменение размера ячейки UICollectionView, вызванное коммутационными макетами

Я звоню setCollectionViewLayout: анимированный: для этого. Анимация размеров ячеек работает отлично. Однако подпункты немного беспорядочны. Каждая ячейка содержит изображение и ярлык (удалили метку на данный момент). Я хочу, чтобы изображение оживляло его изменение размера, поскольку ячейка изменяется в размере, также как и метка.

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

Если удалить Автокомпоновка и выполните следующие действия в initWithFrame:

[[self imageView] setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleRightMargin]; 

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

Я пробовал выкладывать subviews в layoutSubviews, но это дает тот же результат, что и AutoLayout.

Все демонстрации, которые я видел на github для анимации между UICollectionViewLayouts, имеют только цветной фон или подзаголовок, который заполняет всю ячейку. Кто-нибудь сумел заставить это работать?

Ниже приведены изображения того, что происходит (красная линия границы UIImageView):

First Layout

Second Layout

Third Layout

Back to first layout, but subview frames are wrong

+0

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

+0

Привет, у меня такая же проблема. Не могли бы вы сообщить мне, если вы нашли решение, пожалуйста! –

ответ

4

Так что решение я пошел с было отключить Auto Layout (как указал Marty), но я также удалил все Автоматическое изменение размера маски тоже. Я создал три разных жестко кодированных макета в подклассе UICollectionViewCell для каждого UICollectionViewFlowLayout, на котором они будут отображаться.

GSProductCollectionViewCell.м

-(void)setLayoutForWideLayoutWithDestinationSize:(CGSize)size 
{ 
    [[self imageView] setFrame:CGRectMake(5.0f, 5.0f, (int)(size.width * 0.3f), size.height - 10.0f)]; 

    [[self titleLabel] setFrame:CGRectMake(self.imageView.right + 5.0f, 5.0f, size.width - self.imageView.right - 15.0f, 25.0f)]; 
    [[self titleLabel] setFont:[UIFont fontWithName:self.titleLabel.font.fontName size:12.0f]]; 

    [[self titleBackgroundView] setFrame:self.titleLabel.frame]; 
    [[self titleBackgroundView] setAlpha:1.0f]; 

    [[self descriptionLabel] setAlpha:1.0f]; 
    [[self descriptionLabel] setFrame:CGRectMake(self.titleLabel.left,  self.titleLabel.bottom + 5.0f, self.titleLabel.width, 25.0f)]; 

    [...] 
} 

-(void)setLayoutForSqaureLayoutWithDestinationSize:(CGSize)size 
{ 
    [[self imageView] setFrame:CGRectMake(5.0f, 5.0f, size.width - 10.0f, size.height - 10.0f - 30.0f)]; 

    [[self titleLabel] setFrame:CGRectMake(5.0f, size.height - 30.0f, size.width - 10.0f, 25.0f)]; 
    [[self titleLabel] setFont:[UIFont fontWithName:self.titleLabel.font.fontName size:10.0f]]; 

    [[self titleBackgroundView] setFrame:self.titleLabel.frame]; 
    [[self titleBackgroundView] setAlpha:0.0f]; 

    [[self descriptionLabel] setAlpha:0.0f]; 
    [[self descriptionLabel] centerView]; 

    [...] 
} 

-(void)setLayoutWithFrameSize:(CGSize)size forStyle:(GSProductLayoutStyle)layoutStyle 
{ 
    switch (layoutStyle) 
    { 
     case kGSProductLayoutStyleGrid3: 
     case kGSProductLayoutStyleGrid2: 
      [self setLayoutForSqaureLayoutWithDestinationSize:size]; 
      break; 

     case kGSProductLayoutStyleList: 
      [self setLayoutForWideLayoutWithDestinationSize:size]; 
      break; 

     default: 
      break; 
    } 
} 

Затем, когда пользователь выбирает кнопку размещения цикла я перейти к следующему макете и вызова выполните следующие действия в моей ViewController (Имеет UICollectionView):

-(void)setLayoutStyle:(GSProductLayoutStyle)layoutStyle 
{ 
    if (_layoutStyle != layoutStyle) 
    { 
     _layoutStyle = layoutStyle; 

     UICollectionViewFlowLayout *layout; 

     switch (_layoutStyle) 
     { 
      case kGSProductLayoutStyleGrid3: 
       layout = [GSProductCollectionViewGridLayout new]; 
       break; 

      case kGSProductLayoutStyleGrid2: 
       layout = [GSProductCollectionViewGridTwoLayout new]; 
       break; 

      case kGSProductLayoutStyleList: 
       layout = [GSProductCollectionViewListLayout new]; 
       break; 

      default: 
       layout = [GSProductCollectionViewGridLayout new]; 
       break; 
     } 

     CGSize itemSize = layout.itemSize; 

     [self setCollectionViewLayout:layout animated:YES]; 

     [[self visibleCells] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 

      [(GSProductCollectionViewCell*)obj setLayoutStyle:_layoutStyle]; 

      [UIView animateWithDuration:0.3f animations:^{ 

       [(GSProductCollectionViewCell*)obj setLayoutWithFrameSize:itemSize forStyle:self.layoutStyle]; 

      }]; 
     }]; 

    } 
} 

Это дает мне полный контроль над каждый макет в ячейке для каждого типа подкласса FlowLayout. Анимация гладкая, и я также могу угаснуть любые виды, которые я не хочу в определенном макете.

Результатом этого является UICollectionView, который ведет себя так же, как поведение вида сетки iPhone Ebay Apps, но лучше, на мой взгляд.

Извините, я не могу вставить какой-либо код или поместить его в GitHub, как это сделано в Кодексе клиентов. Я рад ответить на любые вопросы.

Приветствия, Brett

1

Привет Бретт присмотревшись везде Ответ, который я нашел, помог мне:

UICollectionView cell subviews do not resize

я оказался поворотным Автокомпоновка назад и просто используя наследие автоматического изменения размера функции IB.

Работает с удовольствием! Надеюсь, это поможет вам!

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

UICollectionView cells, auto layout and collectionview layout changes

35

Чтобы получить эту работу с AutoLayout, вам необходимо поместить следующее в вашем UICollectionViewCell подкласса: продолжительность анимации

- (void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes { 
    [UIView animateWithDuration:animationDuration animations:^{ 
     [self layoutIfNeeded]; 
    }]; 
} 

по умолчанию составляет около 0,33 секунд (определяется экспериментально) ,

+5

Я бы хотел нажать 3 раза на стрелку вверх, к сожалению, только разрешенные. – Dimentar

+0

Сказали всем членам моей команды, чтобы они подняли это вверх FFS! – Shizam

+2

Радиус. Для чего это стоит, это также работает для меня внутри анимированного перехода макета к маке, если я вызываю только «layoutIfNeeded» (т. Е. Не завернутый в блок «animateWithDuration». – par

Смежные вопросы