13

当您在 iOS 7 中的 Messages 应用程序中进行对话时,如果您向上或向下滚动,您会注意到气泡和更多信息,因此说明何时发送消息的文本会弹回原位。

我试图在我自己的表格视图中复制它,但没有找到方法。

我假设它正在使用 UIDynamics,但我不确定如何将其与滚动和内容弹跳联系起来。

任何帮助,将不胜感激

4

3 回答 3

12

如果你想自己复制这种效果,你需要 UIKit Dynamics。我本人对这种效果很感兴趣,并在今年的 WWDC 上对此进行了解释。

看看 WWDC Session 217: Exploring Scroll Views on iOS 7

网上也有阅读使用的组件,比如THSpringyCollectionView

于 2013-11-05T17:39:10.150 回答
11

我也对这种效果感兴趣,在我对网络的研究期间,我发现了这个教程 - http://www.objc.io/issue-5/collection-views-and-uidynamics.html 它实现了相同的想法。

于 2013-11-06T00:53:34.587 回答
3

在此处输入图像描述

您可以像这样在滚动视图中为内容添加弹性反弹:

  1. 设置 UIScrollview 并添加到您的视图中。

    mainScroller = [UIScrollView new];
    mainScroller.frame = CGRectMake(0, 0, w, h);
    mainScroller.bounces = true;
    mainScroller.pagingEnabled = false;
    mainScroller.delegate = self;
    [self.view addSubview:mainScroller];
    
  2. 布局 UIView 并将其添加到您的滚动视图中。

    contentView = [UIView new];
    contentView.frame = CGRectZero;
    [mainScroller addSubview:contentView];
    
  3. 添加子视图您的“内容视图”。

    UIView * unitView = [UIView new];
    unitView.frame = CGRectMake(0, yOff, w, 280);
    [contentView addSubview:unitView]; 
    
  4. 调整 contentView 和 scrollview 的大小以适应内容。下面的w是视图宽度,yOff是内容的总累积高度。

    contentView.frame = CGRectMake(0, 0, w, yOff);
    mainScroller.contentSize = CGSizeMake(w, yOff);
    
  5. 在您的 scrollViewDidScroll 方法中,添加以下代码:

     float y = mainScroller.contentOffset.y;
     contentView.transform = CGAffineTransformMakeTranslation(0, y);
    
     for (UIView * sub in contentView.subviews){
         int index = (int)[contentView.subviews indexOfObject:sub];
         float delay = index * 0.03;
         float duration = 1.0f - delay;
    
         [UIView animateWithDuration:duration
                               delay:delay
              usingSpringWithDamping:0.8
               initialSpringVelocity:0.7
                             options:UIViewAnimationOptionCurveEaseInOut| UIViewAnimationOptionAllowUserInteraction
                          animations:^{
                              sub.transform = CGAffineTransformMakeTranslation(0, -y);
                         }
                     completion:^(BOOL finished){
                     }]; 
     }
    

UIViewAnimationOptionAllowUserInteraction 动画选项允许您立即与内容进行交互。调整延迟、持续时间、弹簧阻尼和弹簧速度变量以满足您的需求。

该代码可以进一步适应触摸检测;就目前而言,弹性反弹起源于 scrollView 的顶部并向下穿过视图,这对于较短的 scrollViews 几乎不明显。

编辑:触摸检测

如果您想允许触摸检测,请在您的 scrollViewDidScroll 方法中替换为这些行:

int index = (int)[contentView.subviews indexOfObject:sub];
int deviation = abs(touchIndex - index);
float delay = deviation * 0.03;
float duration = 1.0f - delay;

新变量 touchIndex 的定义如下:

-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {

    //grab the location of the touch event
    CGPoint location = [scrollView.panGestureRecognizer locationInView:scrollView];
    int yTouch = location.y; //grab y coordinate
    touchIndex = (yTouch - 100) / 100; //calculate the index of the cell, where 100 is the height of the cell

}

如果您有动态单元格高度,请将它们存储在一个数组中,例如“selectedHeights”。然后为下面更新您的 scrollViewWillBeginDragging 方法,其中“tally”浮动设置为 70 以允许标题。

-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {

    //grab the location of the touch event
    CGPoint location = [scrollView.panGestureRecognizer locationInView:scrollView];
    int yTouch = location.y; //grab y coordinate
    float tally = 70.0f;
    for (int n = 0; n < selectedHeights.count; n++){
        float cellHeight = [selectedHeights[n] floatValue];
        tally += cellHeight;
        if (tally > yTouch){
            touchIndex = n;
            break;
        }
    }
}
于 2016-02-02T22:24:33.310 回答