IOS Android Material Design Иерархическое время с использованием UICollectionView

Я хочу сделать анимацию, представленную Android Material Design Иерархическое время в iOS, используя UICollectionView

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

Ответ 1

Один из способов сделать это - добавить ячейки по одному с помощью таймера, и эти ячейки будут расширяться до полного размера, когда они появятся в окне.

#import "ViewController.h"
#import "RDCollectionViewCell.h"

@interface ViewController () <UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout>
@property (weak,nonatomic) IBOutlet UICollectionView *collectionview;
@property (strong,nonatomic) NSMutableArray *mutableArray;
@property (strong,nonatomic) NSArray *data;
@end

@implementation ViewController

-(void)viewDidLoad {
    [super viewDidLoad];
    self.mutableArray = [NSMutableArray new];
    self.data = @[@"one", @"two", @"three", @"four", @"five", @"six", @"seven", @"eight", @"nine", @"ten"];
    [self performSelector:@selector(startTimer) withObject:nil afterDelay:0.5];
}

-(void)startTimer {
    [NSTimer scheduledTimerWithTimeInterval:.05 target:self selector:@selector(addCells:) userInfo:nil repeats:YES];
}


-(void)addCells:(NSTimer *) timer {
    static int counter = 0;
    [self.mutableArray addObject:self.data[counter]];
    counter ++;
    [self.collectionview insertItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:self.mutableArray.count -1 inSection:0]]];
    if (self.mutableArray.count == self.data.count) {
        [timer invalidate];
    }
}


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


-(UICollectionViewCell *) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    RDCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
    cell.contentView.backgroundColor = (indexPath.row % 2 == 0)? [UIColor colorWithRed:180/255.0 green:210/255.0 blue:254/255.0 alpha:1] : [UIColor colorWithRed:50/255.0 green:167/255.0 blue:85/255.0 alpha:1];
    cell.label.text = self.mutableArray[indexPath.row];
    return cell;
}

В пользовательском классе ячеек

@implementation RDCollectionViewCell

-(void)awakeFromNib {
    self.contentView.transform = CGAffineTransformMakeScale(0.01, 0.01);
}


-(void)didMoveToWindow {
    [UIView animateWithDuration:0.3 delay:0.1 options:0 animations:^{
        self.contentView.transform = CGAffineTransformIdentity;
    } completion: nil];
}

Проект можно найти здесь http://jmp.sh/aDw846R

Ответ 2

Подкласс вашей ячейки просмотра коллекции и добавьте этот метод:

class YourCollectionViewCell: UICollectionViewCell {  
   //Some IBOutlets if needed

   func popAfter(delay: NSTimeInterval){
      transform = CGAffineTransformMakeScale(0, 0)
      UIView.animateWithDuration(0.7, delay: delay, options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in
         self.transform = CGAffineTransformMakeScale(1, 1)
      }, completion: nil)      
   }
}

Установите представление коллекции delegate и dataSource в ваш контроллер представления (это можно сделать в Interface Builder). Добавьте константы в контроллер просмотра и просмотрите коллекцию в viewDidAppear для анимации ячеек:

class YourViewController{
   private let numberOfCellsInLine = 3
   private let numberOfVisibleCellsOnTheScreen = 12
   private let baseDelay = 0.15

   override func viewDidAppear(animated: Bool) {
      super.viewDidAppear(animated)
      collectionView.reloadData()
   }
}

Добавьте расширение к контроллеру представления для источника данных и делегата UICollectionView:

extension YourViewController: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout{
   func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int{
      return numberOfCells
   }

   // The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
   func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell{
      let cell = collectionView.dequeueReusableCellWithReuseIdentifier("YourCellID", forIndexPath: indexPath) as YourCollectionViewCell
      //set cell content
      let index = indexPath.row
      let yIndex = index / numberOfCellsInLine
      let delay = Double(index % numberOfCellsInLine + (index >= numberOfVisibleCellsOnTheScreen ? 0 : yIndex)) * baseDelay
      cell.popAfter(delay)
      return cell
   }
}

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

Ответ 3

Что-то вроде этого должно работать. Случайные штуки, брошенные вместе, я знаю.

Здесь очень хорошо написанная ручка того, что вы описываете. В нем вы обнаружите, что рассматриваемая функция синхронизации - это кривая, определенная в CSS как:

cubic-bezier(0.650, 0.045, 0.405, 1.000)

Зная функцию синхронизации, вы можете реализовать эту анимацию в iOS. Здесь ссылка на другой вопрос - она ​​показывает, как снять пользовательские анимации и очень хорошо объясняется.

Пользовательские функции синхронизации в iOS

Может быть, простая математика, но это должно помочь!...я надеюсь.

веселит