3

iOS 7 のマルチタスク UI と非常によく似たカード レイアウトをアプリで作成しようとしています。エンジニアリング WWDC ビデオ Exploring Scroll Views on iOS 7 では、ネストされたスクロール ビューを使用して iOS 7 でその効果を達成したが、そうではなかったと述べています。詳細に進みます。それが最も直感的な方法のように思えたので、UICollectionView を使用していたと思います。

これまでのところ、カスタム UICollectionViewFlowLayout を作成しようとしましたが、非常に難しく、探している機能が提供されません。また、カスタム UICollectionViewCells セルのそれぞれに、サブビューとしてカードを持つスクロールビューがある UICollectionViewFlowLayout で UICollectionView を使用してみました。Autolayout を使用しているので、カードの下部がスクロール ビューの上部と連続するという制約を追加しました。次に、スクロールビューのコンテンツ サイズ内に余分なスペースを追加して、ユーザーが上にスワイプするとカードが画面からスクロールアウトするように見えます。そのようです、

[self.contentView addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-70-[cardView(400)]-650-|"
                                                                          options:0
                                                                          metrics:nil
                                                                            views:views]];

で指定されたスーパービュー|は、セルを満たすスクロールビューです。

またsizeForItemAtIndexPath、エラーが発生するため、画面全体をカバーするのに十分な大きさにすることはできません。

the behavior of the UICollectionViewFlowLayout is not defined because: the item height must be less that the height of the UICollectionView minus the section insets top and bottom values.

問題は、ネストされたスクロールビューを活用しようとする代わりに、カスタム UICollectionViewFlowLayout を作成する必要があるかどうかです。

4

1 に答える 1

1

他の誰かがこの質問に出くわした場合、答えは「いいえ」でした。スワイプアウトのジェスチャーを処理するためにカスタム UICollectionViewFlowLayout を作成するべきではありません。UIScrollViews を使用すると、カスタム レイアウトを実装するよりもはるかに自然な感覚になります。これは、スクロール ビューが iOS 全体で持つのと同じスクロールと勢いを提供します。

ネストされた UIScrollViews を使用して、非常に簡単な方法で問題を解決することができました。私が受け取っていた警告は、実際にはコレクションビューをタブビューコントローラーの最初のタブスポットに配置し、セルが画面全体を占有するという単なるバグだったようです。このバグは、コレクション ビューの背後に別のビューを追加することで解決されました。

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.cardCollectionView registerClass:[SwipeCardCollectionViewCell class] forCellWithReuseIdentifier:kCollectionViewCellIdentifier];
    self.cardCollectionView.alwaysBounceVertical = NO;
    self.cardCollectionView.alwaysBounceHorizontal = YES;
}

- (void)loadView {
    self.view = [[UIView alloc] init];

    self.layout = [[UICollectionViewFlowLayout alloc] init]; 
    self.layout.scrollDirection = UICollectionViewScrollDirectionHorizontal
    self.cardCollectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:self.layout];
    self.cardCollectionView.translatesAutoresizingMaskIntoConstraints = NO;
    self.cardCollectionView.backgroundColor = [UIColor clearColor];
    self.cardCollectionView.delegate = self;
    self.cardCollectionView.dataSource = self;
    [self.view addSubview:self.cardCollectionView];

    NSDictionary *views = @{@"cardCollectionView": self.cardCollectionView}

    [self.view addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[cardCollectionView]|"
                                                                       options:0
                                                                       metrics:nil
                                                                         views:views]];

    [self.view addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[cardCollectionView]|"
                                                                       options:0
                                                                       metrics:nil
                                                                         views:views]];

                                                              views:views]];
}

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{  
    SwipeCardCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kCollectionViewCellIdentifier forIndexPath:indexPath];
    cell.delegate = self;
    return cell;
}

コレクションビューsizeForItemAtIndexPath:を画面のサイズと同じにしました

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    return CGSizeMake(self.cardCollectionView.frame.size.width - CARD_WIDTH_INSET, self.cardCollectionView.frame.size.height);
}

-(CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section{
    return 0.0;
}

-(CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
    return CARD_SPACING;
}

scrollViewWillEndDragging:withVelocity:targetContentOffset:コレクション ビューの両側にコンテンツ インセットを実装して追加することで、コレクション ビューの境界の幅ではなく、カードの幅でカードをページングできるようにしました。

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
    CGFloat inset = CARD_WIDTH_INSET/2.0;
    return UIEdgeInsetsMake(0.0, inset, 0.0, inset);
}

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
    CGFloat cardWidth = self.cardCollectionView.frame.size.width - CARD_WIDTH_INSET;
    NSInteger cardNumber = round(targetContentOffset->x/(cardWidth + CARD_SPACING));
    CGFloat finalOffset = cardNumber*(cardWidth + CARD_SPACING);

   targetContentOffset->x = finalOffset;
}

最後に、作成したカスタム スワイプ セルにスクロール ビューを追加することで、カードを画面からスワイプすることができました。ページングを有効にすると、スプリングボード マルチタスク UI と同じように、カードを画面から右にスワイプできます。そのようです、

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.cardContainerScrollView = [[UIScrollView alloc] init];

        self.cardContainerScrollView.delegate = self;
        self.cardContainerScrollView.pagingEnabled = YES;
        self.cardContainerScrollView.translatesAutoresizingMaskIntoConstraints = NO;
        self.cardContainerScrollView.alwaysBounceHorizontal = NO;
        self.cardContainerScrollView.alwaysBounceVertical = YES;
        self.cardContainerScrollView.showsHorizontalScrollIndicator = NO;
        self.cardContainerScrollView.showsVerticalScrollIndicator = NO;

        self.cardView = [[UIView alloc] init];
        self.cardView.translatesAutoresizingMaskIntoConstraints = NO;
        self.cardView.backgroundColor = [UIColor whiteColor];

        [self.cardContainerScrollView addSubview:self.cardView];

        [self.contentView addSubview:self.cardContainerScrollView];

        NSDictionary *views = @{@"cardView": self.cardView,
                                @"cardContainerScrollView": self.cardContainerScrollView};

        [self.contentView addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[cardContainerScrollView]|"
                                                                                  options:0
                                                                                  metrics:nil
                                                                                    views:views]];

        [self.contentView addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[cardContainerScrollView]|"
                                                                                  options:0
                                                                                  metrics:nil
                                                                                    views:views]];

        [self.contentView addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-70-[cardView(400)]-650-|"
                                                                                  options:0
                                                                                  metrics:nil
                                                                                    views:views]];

        [self.contentView addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[cardView(260)]|"
                                                                                  options:0
                                                                                  metrics:nil
                                                                                    views:views]];

    }
    return self;
}
于 2014-02-15T04:45:29.857 に答える