Implementing a multitasking user interface for iOS 7 tracing with nested scrolls

I'm trying to create a map layout in my application, very similar to the multitasking interface in iOS 7. WWDC engineering video Studying scroll on iOS 7 notes that they used nested scrolls to accomplish this effect in iOS 7, but did not go into details. I would suggest that they used a UICollectionView, as that seemed the most intuitive way.

So far, I have been trying to create a custom UICollectionViewFlowLayout, but it is rather complicated and does not provide the functionality that I am looking for. I also tried using a UICollectionView with a UICollectionViewFlowLayout in which each of the UICollectionViewCells custom cells has a scrollview that has a map as a subquery. I use Autolayout, so I added the restriction that the bottom of the map will be adjacent to the top of the scroll. Then I added extra space in the size of the scroll content so that the map appears as a screen scroll when the user iterates over it. In this way,

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

If the supervisor specified |is a scroll list that populates the cell.

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 , ?

+3
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;
}

, , , . , . ,

- (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;
}
+1

All Articles