2016-08-04 6 views
2

iphone "app closer"のような、水平にスライドしてセルのカスタムレイアウトを実行しようとしている、collectionviewで作業しています。私はこのような効果を達成する方法や、どこから始めるべきかわからないので、いくつかの指針を得ることを望んでいました。 私は自分自身を説明するのが非常に悪いので、どのように振る舞うべきかまで、今の動作から、望ましい効果を説明しようとしました。Collectionviewカスタムセルレイアウト/動作

ありがとうございます!私はthis.Thisのような同様の図で働いている

enter image description here

+1

私はあなたがhttps://github.com/nicklockwood/iCarouselここに示した例を参照すべきだと思う、ここでは、エフェクトの多くの種類があります、そして、あなたが開始すると何 –

+0

感謝を行う方法を少なくともアイデアを取得しますたくさん!カスタムエフェクトのための正確なエンジンのように見えます。 – Imbue

答えて

3

私のプロジェクトのgithubのlinkです。 This is the screenshot of the view 要件と私の見解の唯一の違いは、左のセルもズームする必要があることです。このビューを実現するには、2つの大きな問題が発生しました。

1)2つのセル(左のセルと右のセル)が均等に露出しているときにスクロールを正確に停止します。これは、CollectionView.mファイルに次のコードを含めました。

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset 
{ 
    float pageWidth = 240; // width + space 

    float currentOffset = scrollView.contentOffset.x; 
    float targetOffset = targetContentOffset->x; 
    float newTargetOffset = 0; 

    if (targetOffset > currentOffset) 
     newTargetOffset = ceilf(currentOffset/pageWidth) * pageWidth; 
    else 
     newTargetOffset = floorf(currentOffset/pageWidth) * pageWidth; 

    if (newTargetOffset < 0) 
     newTargetOffset = 0; 
    else if (newTargetOffset > scrollView.contentSize.width) 
     newTargetOffset = scrollView.contentSize.width; 

    targetContentOffset->x = currentOffset; 
    [scrollView setContentOffset:CGPointMake(newTargetOffset, 0) animated:YES]; 

    int index = newTargetOffset/pageWidth; 

    if (index == 0) { // If first index 
     CollectionViewCell *cell =(CollectionViewCell *) [self cellForItemAtIndexPath:[NSIndexPath indexPathForItem:index inSection:0]]; 
     cell.transform = CGAffineTransformIdentity; 
     cell = (CollectionViewCell *)[self cellForItemAtIndexPath:[NSIndexPath indexPathForItem:index + 1 inSection:0]]; 
     //cell.transform = TRANSFORM_CELL_VALUE; 

    }else{ 
     CollectionViewCell *cell =(CollectionViewCell *)[self cellForItemAtIndexPath:[NSIndexPath indexPathForItem:index inSection:0]]; 
     //cell.transform = CGAffineTransformIdentity; 

     index --; // left 
     cell =(CollectionViewCell *)[self cellForItemAtIndexPath:[NSIndexPath indexPathForItem:index inSection:0]]; 
      // cell.transform = TRANSFORM_CELL_VALUE; 
     index ++; 
     index ++; // right 
     cell = (CollectionViewCell *)[self cellForItemAtIndexPath:[NSIndexPath indexPathForItem:index inSection:0]]; 
     //cell.transform = TRANSFORM_CELL_VALUE; 
    } 
} 

2)第二に、あなたはそのために、私はUICollectionViewFlowLayoutクラスを使用していた、要件を達成するために、細胞に適切な制約を提供する必要があります。 これは可視セルに適切な制約を与えます。 FlowLayoutのコードは以下のようになります。

#import "CollectionLayout.h" 


@implementation CollectionLayout 
{ 
    NSIndexPath *mainIndexPath; 
} 

-(void)prepareLayout{ 
    [super prepareLayout]; 
} 

-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{ 
    UICollectionViewLayoutAttributes *attributes = [[super layoutAttributesForItemAtIndexPath:indexPath] copy]; 
    CATransform3D theTransform = CATransform3DIdentity; 
    const CGFloat theScale = 1.05f; 
    theTransform = CATransform3DScale(theTransform, theScale, theScale, 1.0f); 
    attributes.transform3D=theTransform; 
    return attributes; 
} 

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { 
    return YES; 
} 

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{ 
    NSArray *attributesSuper = [super layoutAttributesForElementsInRect:rect]; 
    NSArray *attributes = [[NSArray alloc]initWithArray:attributesSuper copyItems:YES]; 
    NSArray *cellIndices = [self.collectionView indexPathsForVisibleItems]; 
    NSIndexPath *neededIndexPath = [NSIndexPath indexPathForRow:0 inSection:0]; 
    for(NSInteger i=0;i<cellIndices.count;i++){ 
     NSIndexPath *indexPath = [cellIndices objectAtIndex:i]; 
     if(indexPath.row>neededIndexPath.row){ 
      neededIndexPath=indexPath; 
     } 
     NSLog(@"%ld,%ld",(long)indexPath.row,(long)indexPath.section); 
    } 
    if(cellIndices.count==0){ 
     mainIndexPath = [NSIndexPath indexPathForRow:0 inSection:0]; 
    }else{ 
     if(neededIndexPath.row>0) 
      mainIndexPath = [NSIndexPath indexPathForRow:neededIndexPath.row-1 inSection:0]; 
    } 

    for (UICollectionViewLayoutAttributes *attribute in attributes) 
    { 
     [self applyTransformToLayoutAttributes:attribute]; 
    } 
    return attributes; 
} 

-(void) applyTransformToLayoutAttributes:(UICollectionViewLayoutAttributes *)attribute{ 
    if(attribute.indexPath.row == mainIndexPath.row){ 
     attribute.size = CGSizeMake(self.collectionView.bounds.size.width-40, self.collectionView.bounds.size.height); 
     attribute.zIndex+=10; 
    } 
} 

#pragma mark - Transform related 

@end 

あなたは私のgithubのリンクからプロジェクトをクローンしたら、あなたは私がやっていることを容易に理解し、あなたがあなたのview.Youだけあなたを提供する必要があります達成するために独自のコードを書くことができますこのコード部分の制約。 また、セルごとにzIndexを適切に調整する必要があります

-(void) applyTransformToLayoutAttributes:(UICollectionViewLayoutAttributes *)attribute{ 
     if(attribute.indexPath.row == mainIndexPath.row){ 
      attribute.size = CGSizeMake(self.collectionView.bounds.size.width-40, self.collectionView.bounds.size.height); 
      attribute.zIndex+=10; 
     } 
    } 

私はあなたに私の意見があることを望みます。

注:私はgithubコードをiPhone 5でのみテストしましたが、他のデバイス用にちょっと微調整する必要があるかもしれません。

+0

ありがとう!それは素晴らしいインスピレーションでした。私は自分の変種を作りました。それは、まるで期待通りに機能しました。それは素晴らしい仕事です! – Imbue