Google Now like interface on iOS

走远了吗. 提交于 2019-12-02 21:25:58

I don't think there's any tutorial or class that does exactly what you want to do. However, if you don't mind only targeting iOS6 and above you can use an UICollectionView. Using a standard vertical flow layout it shouldn't be that hard to do what you're trying to achieve. Take a look at:

I know these examples don't look exactly like what you're trying to achieve. But once you grasp the basic concepts of UICollectionView using these sites, you'll be able to build the cards-layout in no time.

Update

I created a quick example to show a potential way to handle the panning 'away' of a cell. Make sure to add the necessary code to delete the item from the collection view at //Insert code to delete the cell here, it will then fill in the gap you created by removing the cell.

CLCollectionViewCell.h

#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>

@interface CLCollectionViewCell : UICollectionViewCell <UIGestureRecognizerDelegate>

@property (assign, setter = setDeleted:) BOOL isDeleted;
@property (strong) UIPanGestureRecognizer *panGestureRecognizer;

@end

CLCollectionViewCell.m

#import "CLCollectionViewCell.h"

@implementation CLCollectionViewCell

- (id)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super initWithCoder:aDecoder]) {
        // Create a pan gesture recognizer with self set as the delegate and add it the cell
        _panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureRecognizerDidChange:)];
        [_panGestureRecognizer setDelegate:self]; 
        [self addGestureRecognizer:_panGestureRecognizer];

        // Don't clip to bounds since we want the content view to be visible outside the bounds of the cell
        [self setClipsToBounds:NO];

        // For debugging purposes only: set the color of the content view
        [[self contentView] setBackgroundColor:[UIColor greenColor]];
    }
    return self;
}

- (void)panGestureRecognizerDidChange:(UIPanGestureRecognizer *)panGestureRecognizer {
    if ([self isDeleted]) {
        // The cell should be deleted, leave the state of the cell as it is 
        return;
    }

    // Percent holds a float value between -1 and 1 that indicates how much the user moved his finger relative to the width of the cell
    CGFloat percent = [panGestureRecognizer translationInView:self].x / [self frame].size.width;

    switch ([panGestureRecognizer state]) {
        case UIGestureRecognizerStateChanged: {
            // Create the 'throw animation' and base its current state on the percent
            CGAffineTransform moveTransform = CGAffineTransformMakeTranslation(percent * [self frame].size.width, 0.f);
            CGAffineTransform rotateTransform = CGAffineTransformMakeRotation(percent * M_PI / 20.f);
            CGAffineTransform transform = CGAffineTransformConcat(moveTransform, rotateTransform) ;

            // Apply the transformation to the content view
            [[self contentView] setTransform:transform];

            break;
        }

        case UIGestureRecognizerStateFailed:
        case UIGestureRecognizerStateEnded:
        case UIGestureRecognizerStateCancelled: {
            // Delete the current cell if the absolute value of the percent is above O.7 or the absolute value of the velocity of the gesture is above 600
            if (fabsf(percent) > 0.7f || fabsf([panGestureRecognizer velocityInView:self].x) > 600.f) {
                // The direction is -1 if the gesture is going left and 1 if it's going right
                CGFloat direction = percent < 0.f ? -1.f : 1.f;
                // Multiply the direction to make sure the content view will be removed entirely from the screen
                direction *= 1.5f;

                // Create the transform based on the direction of the gesture
                CGAffineTransform moveTransform = CGAffineTransformMakeTranslation(direction * [self frame].size.width , 0.f);
                CGAffineTransform rotateTransform = CGAffineTransformMakeRotation(direction * M_PI / 20.f);
                CGAffineTransform transform = CGAffineTransformConcat(moveTransform, rotateTransform);

                // Calculate the duration of the animation based on the velocity of the pan gesture recognizer and normalize abnormal high and low values
                CGFloat duration = fabsf(1000.f / [panGestureRecognizer velocityInView:self].x);
                duration = duration > 2.f  ? duration = 2.f  : duration;
                duration = duration < 0.2f ? duration = 0.2f : duration;

                // Animate the 'throwing away' of the cell and update the collection view once it's completed
                [UIView animateWithDuration:duration
                                 animations:^(){
                                     [[self contentView] setTransform:transform];
                                }
                                 completion:^(BOOL finished){
                                     [self setDeleted:YES];

                                     // Insert code to delete the cell here
                                     // e.g. [collectionView deleteItemsAtIndexPaths:@[[collectionView indexPathForCell:self]]];
                }];

            } else {
                // The cell shouldn't be deleted: animate the content view back to its original position
                [UIView animateWithDuration:1.f animations:^(){
                    [[self contentView] setTransform:CGAffineTransformIdentity];
                }];
            }

            break;
        }

        default: {
            break;
        }
    }
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    // Return YES to make sure the pan gesture recognizer doesn't interfere with the gesture recognizer of the collection view
    return YES;
}

@end
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!