iOS Android Material Design Hierarchical Timing using UICollectionView

后端 未结 3 1427
不知归路
不知归路 2021-02-08 06:20

I want to do the animation introduced by Android Material Design Hierarchical Timing in iOS using UICollectionView

Lets say its a collectionView, and resizing the view i

相关标签:
3条回答
  • 2021-02-08 06:43

    One way to do this would be to add the cells one at a time with a timer, and have those cells expand to full size as they come on to the window.

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

    In the custom cell class,

    @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];
    }
    

    The project can be found here, http://jmp.sh/aDw846R

    0 讨论(0)
  • 2021-02-08 06:54

    Subclass your collection view cell and add this method:

    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)      
       }
    }
    

    Set your collection view's delegate and dataSource to your view controller (this can be done in Interface Builder). Add constants to your view controller and reload collection view in viewDidAppear to animate cells:

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

    Add extension to your view controller for UICollectionView datasource & delegate:

    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's content
          let index = indexPath.row
          let yIndex = index / numberOfCellsInLine
          let delay = Double(index % numberOfCellsInLine + (index >= numberOfVisibleCellsOnTheScreen ? 0 : yIndex)) * baseDelay
          cell.popAfter(delay)
          return cell
       }
    }
    

    You can adjust baseDelay and animation duration in Cell's popAfter values to achieve desired timing. Hope this helps and good luck with your app! Feel free to ask any questions.

    0 讨论(0)
  • 2021-02-08 06:58

    Something like this should work. Random pieces thrown together, I know.

    Here's a very well done pen of what you're describing. In it you'll find that the timing function in question is the curve, defined in CSS as:

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

    Knowing the timing function, you can implement this animation in iOS. Here's a link to another question -- it shows how to pull off custom animations and is very well explained.

    Custom timing functions in iOS

    May take some simple math, but this should help! ...i hope.

    cheers

    0 讨论(0)
提交回复
热议问题