Google Now喜欢iOS上的界面 [英] Google Now like interface on iOS

查看:168
本文介绍了Google Now喜欢iOS上的界面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我非常喜欢Android上的Google Now卡片界面。最近它甚至还来到了iOS。

So, I absolutely love Google Now's cards interface on Android.. And recently it has even come to iOS.

是否有任何教程或示例项目可以帮助我为我的iOS应用程序创建卡片界面?

Is there any tutorial, or sample project out there which can help me create a cards interface for my iOS applicaion?

根据我的研究,我可以使用自定义UICollectionViewFlowLayout复制堆叠卡片。

From my research, I have been able to somewhat replicate "stacked" cards using a custom UICollectionViewFlowLayout.

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSArray *allAttributesInRect = [super layoutAttributesForElementsInRect:rect];

    CGPoint centerPoint = CGPointMake(CGRectGetMidX(self.collectionView.bounds), CGRectGetMidY(self.collectionView.bounds));

    for (UICollectionViewLayoutAttributes *cellAttributes in allAttributesInRect)
    {
        if (CGRectContainsPoint(cellAttributes.frame, centerPoint))
        {
            cellAttributes.transform = CGAffineTransformIdentity;
            cellAttributes.zIndex = 1.0;
        }
        else
        {
            cellAttributes.transform = CGAffineTransformMakeScale(0.75, 0.75);
        }
    }

    return allAttributesInRect;
}

然后我将最小行间距设置为负值,使它们显示为堆叠。

Then I set the minimum line spacing to a negative value to make them appear "stacked".

滚动时,我希望卡片保持在底部,只有1辆车可以向上扩展并在屏幕中居中。然后我会在屏幕上滚动该卡片,然后堆叠中的下一张卡片将从堆栈向上滚动并在屏幕上居中。我猜这会动态调整最小行间距吗?

Upon scrolling though, I'd like the cards to stay at the bottom and only 1 car to scale up and center in the screen. Then I would scroll that card off screen and the next 'card' from the stack would scroll up from the stack and center on screen. I'm guessing this would be dynamically adjusting the minimum line spacing?

推荐答案

我认为没有任何教程或课程完全按照自己的意愿行事。但是,如果您不介意仅针对iOS6及更高版本,则可以使用 UICollectionView 。使用标准的垂直流布局,不应该很难做到你想要实现的目标。看看:

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:

  • http://developer.apple.com/library/ios/ipad/#documentation/UIKit/Reference/UICollectionView_class/Reference/Reference.html
  • http://www.appcoda.com/ios-programming-uicollectionview-tutorial/
  • http://www.raywenderlich.com/22324/beginning-uicollectionview-in-ios-6-part-12
  • WWDC 2012 Session 205

我知道这些例子看起来并不像你想要达到的那样。但是一旦你掌握了使用这些网站的 UICollectionView 的基本概念,你就可以立即建立卡片布局。

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.

我创建了一个快速示例,展示了处理单元格平移的潜在方法。确保添加必要的代码以从的集合视图中删除项目//插入代码以删除此处的单元格,然后它将填充您通过删除创建的间隙单元格。

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

这篇关于Google Now喜欢iOS上的界面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆