iOS新浪新闻首页重力感应卡片滚动特效实现浅谈

前段时间,公司的大佬看中了新浪新闻首页卡片滚动的特效,如下图:
新浪新闻卡片效果(网络来源)

拿到效果图一看之下这个效果,这个效果不是那么好做。由于赶在年前就要上线,时间紧迫。没办法只有靠度娘了,多方查找之下,找到了一篇文章-iOS新浪新闻首页卡片滚动特效实现浅谈

当时一看,这个不就是大佬想要的效果么?心中顿时一阵窃喜。大致浏览了一下然后迅速拉到文章底下想看一下demo。结果傻眼了,别说demo了,连部分源码也没有,只提供了大致的思路。我靠,心中一阵拔凉。

然后重新阅读了一下随行的羊的文章。发现他的思路很明确。行吧,那没办法了, 只有先按照他的思路做。

下面进入正题

随行的羊采用了UICollectionView,那我也采用了这个吧,说干就干,下面我直接根据他的思路贴出部分代码,具体的demo 详见github地址:TXCarouselView

问题1:中间的滚动视图是一块一块移动的,停止时距离中间最近的卡片会自动滑动到中间,居中对齐。

- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity {
    CGFloat index = roundf((proposedContentOffset.x+ self.viewHeight / 2 - self.itemHeight / 2) / self.itemHeight);
    proposedContentOffset.x = self.itemHeight * index + self.itemHeight / 2 - self.viewHeight / 2;
    return proposedContentOffset;
}

问题2:中间的滚动视图在滑动的时候发现卡片是叠在一起的,中间的在上层,其他部分在下层,根据距离中间位置的远近来区别上下层。

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    attributes.size = self.itemSize;
    CGFloat cY = self.collectionView.contentOffset.x + self.viewHeight / 2;
    CGFloat attributesY = self.itemHeight * indexPath.row + self.itemHeight / 2;//
    attributes.zIndex = -ABS(attributesY - cY);
}

问题3:中间的滚动视图在滑动的时候发现卡片大小不一致,中间的最大,越靠近边框越小。同样是在layoutAttributesForItemAtIndexPath中:

    CGFloat scale = 1 - ABS(delta) / (self.itemHeight * 6.0) * cos(ratio * M_2_PI*0.9);
    attributes.transform = CGAffineTransformMakeScale(scale, scale);

问题4:中间的滚动视图在滑动的时候发现滑动的距离和卡片移动的距离并不是成正比,而是按照不断变化的加速度移动的。

centerY = cY + sin(ratio * 1.31) * self.itemHeight * INTERSPACEPARAM*2.2+index1;

问题5:中间的滚动视图滑到左右边缘时视图透明度改变。

这个也可以根据的centerY来确定,attributes这个布局类中提供了
@property (nonatomic) CGFloat alpha;
所以也可以实现。

问题6:循环滚动方案的实现(额。这里我用的创建多组数据来实现的,因为cell有复用机制,所以创建多组数据也没有关系。只要能顺滑就行了)

self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];

问题7:上下滑动表格时,中间的滚动视图要跟着一起滑动,上滑时向左移动,下滑时向右移动。

这里用kvo监听一下就可以了
 [self.superScrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];

问题8:左右晃动手机时,中间的滚动视图要跟着一起滑动,向左晃动时卡片向左移动,向右晃动时卡片向右移动。

这个用苹果自带的加速计和陀螺仪就行了,但是其中有很多问题需要解决,但是细致调试之下完美解决了具体代码详见github地址:TXCarouselView

问题9:需要保证刚才提到的3种控制方式互不干扰。

@interface  carouselCurrentState : NSObject
@property (nonatomic, assign) BOOL isOverturnState; //是否进入翻转状态
@property (nonatomic, assign) BOOL isDragState;     //是否处于拖动状态
@property (nonatomic, assign) BOOL isDidScroll;     //是否处于滑动状态
@property (nonatomic, assign) BOOL isCenter;        //是否处于回到正中状态
@property (nonatomic, assign) BOOL isRestrict;      //是否处于限制重力感应
@property (nonatomic, assign) CGFloat lastCarouselPoint;//上一个lastPoint

@end

@implementation carouselCurrentState
@end

问题10:拖动,滑动, 重力感应结束需要回到正中位置。

1.拖动
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity {
    CGFloat index = roundf((proposedContentOffset.x+ self.viewHeight / 2 - self.itemHeight / 2) / self.itemHeight);
    proposedContentOffset.x = self.itemHeight * index + self.itemHeight / 2 - self.viewHeight / 2;
    return proposedContentOffset;
}
2.tableview滑动结束时,需要回到初始位置,这里我试过用kvo监听superScrollView的滑动结束,但是没有找到方法。用通知就太low了,然后在朋友的建议下用了runLoop:
- (void)creatUIRunloopObserver:(CFOptionFlags)flag {
    CFRunLoopRef runLoop = CFRunLoopGetCurrent();
    CFStringRef runLoopMode = (__bridge CFStringRef)UITrackingRunLoopMode;
    CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault, flag, true, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity _activity) {
        switch (_activity) {
            case kCFRunLoopEntry: {
                NSLog(@"即将进入Loop");
            }
                break;
            case kCFRunLoopBeforeTimers: {
                NSLog(@"即将处理 Timer");
                break;
            }
            case kCFRunLoopBeforeSources:
                NSLog(@"即将处理 Source");
                break;
            case kCFRunLoopBeforeWaiting:
                NSLog(@"即将进入休眠");
                break;
            case kCFRunLoopAfterWaiting:
                NSLog(@"刚从休眠中唤醒");
                break;
            case kCFRunLoopExit:
                NSLog(@"UITracking 即将退出Loop");
                self.currentState.isOverturnState = NO;
                self.currentState.isDragState = NO;
                self.currentState.isDidScroll = NO;
                self.currentState.isCenter = NO;
                self.currentState.isRestrict = NO;
                self.currentState.lastCarouselPoint = 0.0f;
                [self setSlideEnd];
                break;
            default:
                break;
        }
    });
    
    CFRunLoopAddObserver(runLoop, observer, runLoopMode);
}

好了,大部分的细节就不细说了,如果能给一个star就最好了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容